Ejemplo n.º 1
0
def collectDenom(expr, subsDict):
    """ collect input expression in terms of common denominators """
    commons = {}
    for arg in expr.args:
        if sy.denom(arg) in commons:
            commons[sy.denom(arg)] += sy.numer(arg)
        else:
            commons[sy.denom(arg)] = sy.numer(arg)
    return sum([
        sy.simplify(commons[denom]).subs(subsDict) / denom for denom in commons
    ])
Ejemplo n.º 2
0
    def __new__(cls, b, e, evaluate=True):
        from sympy.functions.elementary.exponential import exp_polar
        from sympy.functions import log
        # don't optimize "if e==0; return 1" here; it's better to handle that
        # in the calling routine so this doesn't get called
        b = _sympify(b)
        e = _sympify(e)
        if evaluate:
            if e is S.Zero:
                return S.One
            elif e is S.One:
                return b
            elif S.NaN in (b, e):
                if b is S.One:  # already handled e == 0 above
                    return S.One
                return S.NaN
            else:
                if e.func == log:
                    if len(e.args) == 2:
                        lbase = e.args[1]
                    else:
                        lbase = S.Exp1
                    if lbase == b:
                        return e.args[0]

                if e is Mul and e.args[1].func == log:
                    if len(e.args[1].args) == 2:
                        lbase = e.args[1].args[1]
                    else:
                        lbase = S.Exp1
                    if lbase == b:
                        return e.args[1].args[0] ** e.args[0]

                # recognize base as E
                if not e.is_Atom and b is not S.Exp1 and b.func is not exp_polar:
                    from sympy import numer, denom, log, sign, im, factor_terms
                    c, ex = factor_terms(e, sign=False).as_coeff_Mul()
                    den = denom(ex)
                    if den.func is log and den.args[0] == b:
                        return S.Exp1**(c*numer(ex))
                    elif den.is_Add:
                        s = sign(im(b))
                        if s.is_Number and s and den == \
                                log(-factor_terms(b, sign=False)) + s*S.ImaginaryUnit*S.Pi:
                            return S.Exp1**(c*numer(ex))

                obj = b._eval_power(e)
                if obj is not None:
                    return obj
        obj = Expr.__new__(cls, b, e)
        obj.is_commutative = (b.is_commutative and e.is_commutative)
        return obj
Ejemplo n.º 3
0
def entropy_of_value(value):
    """Returns "min entropy" that would give probability of getting this value."""
    if isinstance(value, display.Decimal):
        return entropy_of_value(sympy.numer(value))

    if is_non_integer_rational(value):
        numer = sympy.numer(value)
        denom = sympy.denom(value)
        return entropy_of_value(numer) + entropy_of_value(denom)
    elif not is_integer(value):
        raise ValueError('Unhandled value: {}'.format(value))

    # Note: we sample integers in a range of size approx 10**entropy about zero,
    # so assume that `abs(value)` is about half of the upper range.
    return math.log10(5 * abs(value) + 1)
Ejemplo n.º 4
0
def normalize_poly(poly):
    poly = sp.simplify(poly)
    num = sp.Poly(sp.expand(sp.numer(poly)))
    den = sp.Poly(sp.expand(sp.denom(poly)))
    num /= den.coeffs()[0]
    den /= den.coeffs()[0]
    return num / den
Ejemplo n.º 5
0
def e2nd(expression):
    """ basic helper function that accepts a sympy expression, expands it, 
    attempts to simplify it, and returns a numerator and denomenator pair for the instantiation of a scipy LTI system object. """
    expression = expression.expand().cancel()
    n = sympy.Poly(sympy.numer(expression), s).all_coeffs()
    d = sympy.Poly(sympy.denom(expression), s).all_coeffs()
    return ([float(x) for x in n], [float(x) for x in d])
def _div_op(value, sample_args, rationals_allowed):
  """Returns sampled args for `ops.Div`."""
  assert rationals_allowed  # should be True if this function gets invoked
  entropy, sample_args = sample_args.peel()

  numer = sympy.numer(value)
  denom = sympy.denom(value)

  if sample_args.count == 1:
    mult = number.integer(entropy, signed=True, min_abs=1)
    op_args = [numer * mult, denom * mult]
  elif sample_args.count == 2:
    if numer == 0 or random.choice([False, True]):
      x = number.integer(entropy, signed=True, min_abs=1, coprime_to=denom)
      op_args = [sympy.Rational(x * numer, denom), x]
    else:
      x = number.integer(entropy, signed=True, min_abs=1, coprime_to=numer)
      op_args = [x, sympy.Rational(x * denom, numer)]
  else:
    assert sample_args.count >= 3
    p2, p1 = _split_factors(numer)
    q1, q2 = _split_factors(denom)
    entropy -= _entropy_of_factor_split(numer) + _entropy_of_factor_split(denom)
    entropy_r = random.uniform(0, entropy)
    entropy_s = entropy - entropy_r
    r = number.integer(entropy_r, signed=True, min_abs=1, coprime_to=q1*p2)
    s = number.integer(entropy_s, signed=False, min_abs=1, coprime_to=p1*q2)
    op_args = [sympy.Rational(r*p1, s*q1), sympy.Rational(r*q2, s*p2)]

  return ops.Div, op_args, sample_args
Ejemplo n.º 7
0
	def simplify(self):
		self._eqn = sympy.factor(sympy.numer(sympy.factor(self._eqn)))
		if isinstance(self._eqn, sympy.Mul):
			def is_not_constant(ex):
				sym = ex.free_symbols
				return x in sym or y in sym or z in sym
			self._eqn = sympy.Mul(*(filter(is_not_constant, self._eqn.args)))
Ejemplo n.º 8
0
 def pxhatsqrd_Ci_polylike_eqn(self, sub_: Dict, pzhat_: float) -> Eq:
     r"""Define polynomial-form equation for :math:`\hat{p}_x^2`."""
     tmp = (self.H_Ci_eqn.rhs.subs({
         pzhat: pzhat_,
         H: Rational(1, 2),
         mu: eta / 2
     }).subs(omitdict(sub_, [Ci])))**2
     return Eq(4 * numer(tmp) - denom(tmp), 0)
Ejemplo n.º 9
0
    def __new__(cls, b, e, evaluate=None):
        if evaluate is None:
            evaluate = global_evaluate[0]
        from sympy.functions.elementary.exponential import exp_polar

        b = _sympify(b)
        e = _sympify(e)
        if evaluate:
            if e is S.Zero:
                return S.One
            elif e is S.One:
                return b
            elif e.is_integer and _coeff_isneg(b):
                if e.is_even:
                    b = -b
                elif e.is_odd:
                    return -Pow(-b, e)
            if b is S.One:
                if e in (S.NaN, S.Infinity, -S.Infinity):
                    return S.NaN
                return S.One
            elif S.NaN in (
                    b,
                    e):  # XXX S.NaN**x -> S.NaN under assumption that x != 0
                return S.NaN
            else:
                # recognize base as E
                if not e.is_Atom and b is not S.Exp1 and b.func is not exp_polar:
                    from sympy import numer, denom, log, sign, im, factor_terms
                    c, ex = factor_terms(e, sign=False).as_coeff_Mul()
                    den = denom(ex)
                    if den.func is log and den.args[0] == b:
                        return S.Exp1**(c * numer(ex))
                    elif den.is_Add:
                        s = sign(im(b))
                        if s.is_Number and s and den == \
                                log(-factor_terms(b, sign=False)) + s*S.ImaginaryUnit*S.Pi:
                            return S.Exp1**(c * numer(ex))

                obj = b._eval_power(e)
                if obj is not None:
                    return obj
        obj = Expr.__new__(cls, b, e)
        obj.is_commutative = (b.is_commutative and e.is_commutative)
        return obj
Ejemplo n.º 10
0
def complexity_rat(N):
    '''
    Compute the complexity of a rational number.
    '''
    a, b = int(sp.numer(N)), int(sp.denom(N))
    C_A = complexity_integer(a)
    C_B = complexity_integer(b)
    C_M = max(a, b)
    return 0.5 * (C_A + C_B) + 0.5 * C_M
Ejemplo n.º 11
0
    def __new__(cls, b, e, evaluate=None):
        if evaluate is None:
            evaluate = global_evaluate[0]
        from sympy.functions.elementary.exponential import exp_polar

        b = _sympify(b)
        e = _sympify(e)
        if evaluate:
            if e is S.Zero:
                return S.One
            elif e is S.One:
                return b
            elif e.is_integer and _coeff_isneg(b):
                if e.is_even:
                    b = -b
                elif e.is_odd:
                    return -Pow(-b, e)
            if b is S.One:
                if e in (S.NaN, S.Infinity, -S.Infinity):
                    return S.NaN
                return S.One
            elif S.NaN in (b, e):  # XXX S.NaN**x -> S.NaN under assumption that x != 0
                return S.NaN
            else:
                # recognize base as E
                if not e.is_Atom and b is not S.Exp1 and b.func is not exp_polar:
                    from sympy import numer, denom, log, sign, im, factor_terms
                    c, ex = factor_terms(e, sign=False).as_coeff_Mul()
                    den = denom(ex)
                    if den.func is log and den.args[0] == b:
                        return S.Exp1**(c*numer(ex))
                    elif den.is_Add:
                        s = sign(im(b))
                        if s.is_Number and s and den == \
                                log(-factor_terms(b, sign=False)) + s*S.ImaginaryUnit*S.Pi:
                            return S.Exp1**(c*numer(ex))

                obj = b._eval_power(e)
                if obj is not None:
                    return obj
        obj = Expr.__new__(cls, b, e)
        obj.is_commutative = (b.is_commutative and e.is_commutative)
        return obj
Ejemplo n.º 12
0
def e2nd(expression):
	""" basic helper function that accepts a sympy expression, expands it,
	attempts to simplify it, and returns a numerator and denomenator pair for the instantiation of a scipy
	LTI system object. """
	expression = expression.expand()
	expression = expression.cancel()
	n = sympy.Poly(sympy.numer(expression), s).all_coeffs()
	d = sympy.Poly(sympy.denom(expression), s).all_coeffs()
	n = map(float, n)
	d = map(float, d)
	return (n, d)
Ejemplo n.º 13
0
    def __new__(cls, b, e, evaluate=None):
        if evaluate is None:
            evaluate = global_evaluate[0]
        from sympy.functions.elementary.exponential import exp_polar

        # don't optimize "if e==0; return 1" here; it's better to handle that
        # in the calling routine so this doesn't get called
        b = _sympify(b)
        e = _sympify(e)
        if evaluate:
            if e is S.Zero:
                return S.One
            elif e is S.One:
                return b
            elif b is S.One:
                if e in (S.NaN, S.Infinity, -S.Infinity):
                    return S.NaN
                return S.One
            elif S.NaN in (b, e):
                return S.NaN
            else:
                # recognize base as E
                if not e.is_Atom and b is not S.Exp1 and b.func is not exp_polar:
                    from sympy import numer, denom, log, sign, im, factor_terms
                    c, ex = factor_terms(e, sign=False).as_coeff_Mul()
                    den = denom(ex)
                    if den.func is log and den.args[0] == b:
                        return S.Exp1**(c * numer(ex))
                    elif den.is_Add:
                        s = sign(im(b))
                        if s.is_Number and s and den == \
                                log(-factor_terms(b, sign=False)) + s*S.ImaginaryUnit*S.Pi:
                            return S.Exp1**(c * numer(ex))

                obj = b._eval_power(e)
                if obj is not None:
                    return obj
        obj = Expr.__new__(cls, b, e)
        obj.is_commutative = (b.is_commutative and e.is_commutative)
        return obj
Ejemplo n.º 14
0
def sympy_to_tf(G, data):
    """convert a discrete transfer function in sympy to a contorl.tf"""
    z = sympy.symbols('z')
    Gs = G.subs(data)
    try:
        num = np.array(sympy.Poly(sympy.numer(Gs), z).all_coeffs(),
                       dtype=float)
        den = np.array(sympy.Poly(sympy.denom(Gs), z).all_coeffs(),
                       dtype=float)
    except Exception:
        raise TypeError('failed to convert expression to float polynomials: ',
                        Gs)
    return control.tf(num, den, 1.0 / data['f_s'])
Ejemplo n.º 15
0
def tustin(tf, sRate):
    s = getMapping(tf)['s']
    T = 1 / sRate
    poles = sympy.roots(sympy.denom(tf), s, multiple=True)
    centroid = np.mean(np.abs(poles))
    invz = sympy.Symbol('invz', real=True)
    # normalized center frequency derived from poles of filter SISO transfer function
    w0 = 2 * np.pi * centroid / (sRate * 2 * np.pi)
    # modified bilinear transform w/ frequency warping
    bt = w0 / sympy.tan(w0 * T / 2) * ((1 - invz) / (1 + invz))
    dt = sympy.simplify(tf.subs({s: bt}))
    b = sympy.Poly(sympy.numer(dt)).all_coeffs()[::-1]
    a = sympy.Poly(sympy.denom(dt)).all_coeffs()[::-1]
    normalize = lambda x: float(x / a[0])
    return (map(normalize, b), map(normalize, a))
Ejemplo n.º 16
0
def tustin(tf, sRate):
	s =	getMapping(tf)['s']
	T = 1/sRate
	poles = sympy.roots(sympy.denom(tf), s, multiple=True)
	centroid = np.mean(np.abs(poles))
	invz = sympy.Symbol('invz', real=True)
	# normalized center frequency derived from poles of filter SISO transfer function
	w0 = 2*np.pi*centroid/(sRate*2*np.pi)
	# modified bilinear transform w/ frequency warping
	bt = w0/sympy.tan(w0*T/2) * ((1-invz)/(1+invz))
	dt = sympy.simplify(tf.subs({s: bt}))
	b = sympy.Poly(sympy.numer(dt)).all_coeffs()[::-1]
	a = sympy.Poly(sympy.denom(dt)).all_coeffs()[::-1]
	normalize = lambda x: float(x/a[0])
	return (map(normalize, b), map(normalize, a))
Ejemplo n.º 17
0
def mutate_rat(value, *, keep_sign=True, mutate_up=None):
    '''Mutate rational number'''

    r = random.random()
    numer, denom = sp.numer(value), sp.denom(value)

    # swap numerator and denominator
    if r < 0.20:
        numer, denom = (mutate_int(denom, mutate_up=mutate_up, keep_sign=keep_sign),
                        mutate_int(numer, mutate_up=mutate_up))
    # mutate numerator
    elif r < 0.65:
        numer = mutate_int(numer, mutate_up=mutate_up, keep_sign=keep_sign)
    # mutate denominator
    else:
        denom = mutate_int(denom, mutate_up=mutate_up, keep_sign=keep_sign)

    return sp.Rational(numer, denom or 1)
Ejemplo n.º 18
0
  def _rational_to_string(self, rational):
    """Converts a rational to words, e.g., "two thirds"."""
    numer = sympy.numer(rational)
    denom = sympy.denom(rational)

    numer_words = self._to_string(numer)

    if denom == 1:
      return numer_words

    if denom <= 0 or denom >= len(_PLURAL_DENOMINATORS):
      raise ValueError('Unsupported denominator {}.'.format(denom))

    if numer == 1:
      denom_word = _SINGULAR_DENOMINATORS[denom]
    else:
      denom_word = _PLURAL_DENOMINATORS[denom]

    return '{} {}'.format(numer_words, denom_word)
Ejemplo n.º 19
0
  def __init__(self, value):
    """Initializes a `Decimal`.

    Args:
      value: (Sympy) value to display as a decimal.

    Raises:
      ValueError: If `value` cannot be represented as a non-terminating decimal.
    """
    self._value = sympy.Rational(value)

    numer = int(sympy.numer(self._value))
    denom = int(sympy.denom(self._value))

    denom_factors = list(sympy.factorint(denom).keys())
    for factor in denom_factors:
      if factor not in [2, 5]:
        raise ValueError('Cannot represent {} as a non-recurring decimal.'
                         .format(value))
    self._decimal = decimal.Decimal(numer) / decimal.Decimal(denom)
Ejemplo n.º 20
0
def _delta_invariant(g,u,v,u0,v0):
    """
    Returns the delta invariant corresponding to the singular point
    `singular_pt` = [alpha, beta, gamma] on the plane algebraic curve
    f(x,y) = 0.
    """
    # compute Puiseux expansions at u=u0 and filter out only those
    # with v(t=0) == v0. We only chose one y=y(x) Puiseux series for
    # each place as a representative to prevent over-counting by using
    # the "grouped=True" flag in Puiseux
    P = puiseux(g,u,v,u0,nterms=0,parametric=_t,grouped=True)
    P_x = puiseux(g,u,v,u0,nterms=0,parametric=False,grouped=True)
    P_x_v0 = []
    for i in range(len(P)):
        X,Y = P[i]
        p = P_x[i][0]
        if Y.subs(_t,0).simplify() == v0:
            # store the index as well so we know which parametric form
            # corresponds to this puiseux series.
            P_x_v0.append((p,i))

    # now obtain ungrouped series
    P_x = puiseux(g,u,v,u0,nterms=0,parametric=False)
    
    # for each place compute its contribution to the delta invariant
    delta = sympy.Rational(0,1)
    for i in range(len(P_x_v0)):
        yhat, place_index = P_x_v0[i]
        j = P_x.index(yhat)
        IntPj = Int(j,P_x,u,u0)

        # obtain the ramification index by retreiving the
        # corresponding parametric form. By definition, this
        # parametric series satisfies Y(t=0) = v0
        X,Y = P[place_index]
        rj = (X-u0).as_coeff_exponent(_t)[1]
        delta += sympy.Rational(rj * IntPj - rj + 1, 2)

    return sympy.numer(delta)
Ejemplo n.º 21
0
def poleres2pz(poles,residues,offset,slope, maxsteps=500):
    """
    Convert a pole-resiude representation of a TF -- 
     
        f(s) = Sum [r/(s-p)] + k + s * h 

    to a pole zero representation

        f(s) = Sum[s-z] / Sum[s-p]
    """
    from sympy import Symbol, together, expand, numer, denom, nroots

    x = Symbol('x')
    f = sum([r/(x-p) for p,r in zip(poles, residues)])
    f += offset + slope*x

    ft = together(f)
    nf = expand(numer(ft))

    zeros = nroots(nf,maxsteps=maxsteps)
    return np.array([complex(xx) for xx in poles]), np.array([complex(xx) for
                                                              xx in zeros])
def _mul_op(value, sample_args, rationals_allowed):
  """Returns sampled args for `ops.Mul`."""
  if sample_args.count >= 3:
    _, op_args, sample_args = _div_op(value, sample_args, rationals_allowed)
    op_args = [op_args[0], sympy.Integer(1) / op_args[1]]
  elif sample_args.count == 1:
    entropy, sample_args = sample_args.peel()
    assert _entropy_of_factor_split(value) >= entropy
    op_args = _split_factors(value)
  else:
    assert sample_args.count == 2
    entropy, sample_args = sample_args.peel()
    numer = sympy.numer(value)
    denom = sympy.denom(value)
    p1, p2 = _split_factors(numer)
    entropy -= _entropy_of_factor_split(numer)
    mult = number.integer(entropy, signed=True, min_abs=1, coprime_to=p1)
    op_args = [p1 / (mult * denom), p2 * mult]

  if random.choice([False, True]):
    op_args = list(reversed(op_args))

  return ops.Mul, op_args, sample_args
Ejemplo n.º 23
0
def symmetryDetection(allVariables,
                      diffEquations,
                      observables,
                      obsFunctions,
                      initFunctions,
                      predictions,
                      predFunctions,
                      ansatz='uni',
                      pMax=2,
                      inputs=[],
                      fixed=[],
                      parallel=1,
                      allTrafos=False,
                      timeTrans=False,
                      pretty=True,
                      suffix=''):

    n = len(allVariables)
    m = len(diffEquations)
    h = len(observables)

    ###########################################################################################
    #############################     prepare equations    ####################################
    ###########################################################################################
    sys.stdout.write('Preparing equations...')
    sys.stdout.flush()

    # make infinitesimal ansatz
    infis, diffInfis, rs = makeAnsatz(ansatz, allVariables, m, len(inputs),
                                      pMax, fixed)

    # get infinitesimals of time transformation
    if timeTrans:
        rs.append(spy.var('r_T_1'))
        diffInfiT = rs[-1]
        allVariables += [T]
    else:
        diffInfiT = None

    # and convert to polynomial
    infis, diffInfis = transformInfisToPoly(infis, diffInfis, allVariables, rs,
                                            parallel, ansatz)

    diffInfiT = Apoly(diffInfiT, allVariables, rs)

    ### extract numerator and denominator of equations
    #differential equations
    numerators = [0] * m
    denominators = [0] * m
    for k in range(m):
        rational = spy.together(diffEquations[k])
        numerators[k] = Apoly(spy.numer(rational), allVariables, None)
        denominators[k] = Apoly(spy.denom(rational), allVariables, None)

    #observation functions
    obsNumerators = [0] * h
    obsDenominatros = [0] * h
    for k in range(h):
        rational = spy.together(obsFunctions[k])
        obsNumerators[k] = Apoly(spy.numer(rational), allVariables, None)
        obsDenominatros[k] = Apoly(spy.denom(rational), allVariables, None)

    #initial functions
    if len(initFunctions) != 0:
        initNumerators = [0] * m
        initDenominatros = [0] * m
        for k in range(m):
            rational = spy.together(initFunctions[k])
            initNumerators[k] = Apoly(spy.numer(rational), allVariables, None)
            initDenominatros[k] = Apoly(spy.denom(rational), allVariables,
                                        None)
    else:
        initNumerators = []
        initDenominatros = []

    ### calculate numerator of derivatives of equations
    #differential equatioins
    derivativesNum = [0] * m
    for i in range(m):
        derivativesNum[i] = [0] * n
    for k in range(m):
        for l in range(n):
            derivativesNum[k][l] = Apoly(None, allVariables, None)
            derivativesNum[k][l].add(numerators[k].diff(l).mul(
                denominators[k]))
            derivativesNum[k][l].sub(numerators[k].mul(
                denominators[k].diff(l)))

    #observation functions
    obsDerivativesNum = [0] * h
    for i in range(h):
        obsDerivativesNum[i] = [0] * n
    for k in range(h):
        for l in range(n):
            obsDerivativesNum[k][l] = Apoly(None, allVariables, None)
            obsDerivativesNum[k][l].add(obsNumerators[k].diff(l).mul(
                obsDenominatros[k]))
            obsDerivativesNum[k][l].sub(obsNumerators[k].mul(
                obsDenominatros[k].diff(l)))

    #initial functions
    if len(initFunctions) != 0:
        initDerivativesNum = [0] * len(initFunctions)
        for i in range(m):
            initDerivativesNum[i] = [0] * n
        for k in range(m):
            for l in range(n):
                initDerivativesNum[k][l] = Apoly(None, allVariables, None)
                initDerivativesNum[k][l].add(initNumerators[k].diff(l).mul(
                    initDenominatros[k]))
                initDerivativesNum[k][l].sub(initNumerators[k].mul(
                    initDenominatros[k].diff(l)))
    else:
        initDerivativesNum = []

    sys.stdout.write('\rPreparing equations...done\n')
    sys.stdout.flush()

    ###########################################################################################
    ############################     build linear system    ###################################
    ###########################################################################################
    sys.stdout.write('\nBuilding system...')
    sys.stdout.flush()

    rSystem = buildSystem(numerators, denominators, derivativesNum,
                          obsDerivativesNum, initDenominatros,
                          initDerivativesNum, initFunctions, infis, diffInfis,
                          diffInfiT, allVariables, rs, parallel, ansatz)

    sys.stdout.write('done\n')
    sys.stdout.flush()

    ###########################################################################################
    ##############################     solve system    ########################################
    ###########################################################################################
    sys.stdout.write('\nSolving system of size ' + str(rSystem.shape[0]) + 'x' +\
         str(rSystem.shape[1]) + '...')
    sys.stdout.flush()

    #get LU decomposition from scipy
    rSystem = scipy.linalg.lu(rSystem, permute_l=True)[1]

    #calculate reduced row echelon form
    rSystem, pivots = getrref(rSystem)

    sys.stdout.write('done\n')
    sys.stdout.flush()

    ###########################################################################################
    #############################     process results    ######################################
    ###########################################################################################
    sys.stdout.write('\nProcessing results...')
    sys.stdout.flush()

    # calculate solution space
    sys.stdout.write('\n  calculating solution space')
    sys.stdout.flush()
    baseMatrix = nullSpace(rSystem, pivots)

    #substitute solutions into infinitesimals
    #(and remove the ones with common parameter factors)
    sys.stdout.write('\n  substituting solutions')
    sys.stdout.flush()
    infisAll = []
    for l in range(baseMatrix.shape[1]):
        infisTmp = [0] * n
        for i in range(len(infis)):
            infisTmp[i] = infis[i].getCopy()
            infisTmp[i].rs = baseMatrix[:, l]
            infisTmp[i] = infisTmp[i].as_expr()
        if timeTrans:
            infisTmp.append(baseMatrix[-1, l] * T)

        if allTrafos:
            infisAll.append(infisTmp)
        else:
            if not checkForCommonFactor(infisTmp, allVariables, m):
                infisAll.append(infisTmp)

    print('')
    sys.stdout.write('done\n')
    sys.stdout.flush()

    # print transformations
    print('\n\n')
    if len(infisAll) != 0:
        printTransformations(infisAll, allVariables, pretty, suffix)

    ###########################################################################################
    ############################     check predictions    #####################################
    ###########################################################################################
    if predictions != False:
        checkPredictions(predictions, predFunctions, infisAll, allVariables)

    print(
        time.strftime('\nTotal time: %Hh:%Mm:%Ss',
                      time.gmtime(time.time() - t0)))
Ejemplo n.º 24
0
    def ratfun(self, expr, z, n, **kwargs):

        expr = expr / z

        # Handle special case 1 / (z**m * (z - 1)) since this becomes u[n - m]
        # The default method produces u[n] - delta[n] for u[n-1].  This is correct
        # but can be simplified.
        # In general, 1 / (z**m * (z - a)) becomes a**n * u[n - m]

        if (len(expr.args) == 2 and expr.args[1].is_Pow
                and expr.args[1].args[0].is_Add
                and expr.args[1].args[0].args[0] == -1
                and expr.args[1].args[0].args[1] == z):

            delay = None
            if expr.args[0] == z:
                delay = 1
            elif expr.args[0].is_Pow and expr.args[0].args[0] == z:
                a = expr.args[0].args[1]
                if a.is_positive:
                    warn('Dodgy z-transform 1.  Have advance of unit step.')
                elif not a.is_negative:
                    warn(
                        'Dodgy z-transform 2.  May have advance of unit step.')
                delay = -a
            elif (expr.args[0].is_Pow and expr.args[0].args[0].is_Pow
                  and expr.args[0].args[0].args[0] == z
                  and expr.args[0].args[0].args[1] == -1):
                a = expr.args[0].args[1]
                if a.is_negative:
                    warn('Dodgy z-transform 3.  Have advance of unit step.')
                elif not a.is_positive:
                    warn(
                        'Dodgy z-transform 4.  May have advance of unit step.')
                delay = a

            if delay is not None:
                return UnitStep(n - delay), sym.S.Zero

        zexpr = Ratfun(expr, z)

        Q, M, D, delay, undef = zexpr.as_QMA()

        cresult = sym.S.Zero
        uresult = sym.S.Zero

        if Q:
            Qpoly = sym.Poly(Q, z)
            C = Qpoly.all_coeffs()
            for m, c in enumerate(C):
                cresult += c * UnitImpulse(n - len(C) + m + 1)

        # There is problem with determining residues if
        # have 1/(z*(-a/z + 1)) instead of 1/(-a + z).  Hopefully,
        # simplify will fix things...
        expr = (M / D).simplify()
        # M and D may contain common factors before simplification, so redefine M and D
        M = sym.numer(expr)
        D = sym.denom(expr)
        for factor in expr.as_ordered_factors():
            if factor == sym.oo:
                return factor, factor

        zexpr = Ratfun(expr, z, **kwargs)
        poles = zexpr.poles(damping=kwargs.get('damping', None))
        poles_dict = {}
        for pole in poles:
            # Replace cos()**2-1 by sin()**2
            pole.expr = TR6(sym.expand(pole.expr))
            pole.expr = sym.simplify(pole.expr)
            # Remove abs value from sin()
            pole.expr = pole.expr.subs(sym.Abs, sym.Id)
            poles_dict[pole.expr] = pole.n

        # Juergen Weizenecker HsKa

        # Make two dictionaries in order to handle them differently and make
        # pretty expressions
        if kwargs.get('pairs', True):
            pole_pair_dict, pole_single_dict = pair_conjugates(poles_dict)
        else:
            pole_pair_dict, pole_single_dict = {}, poles_dict

        # Make n (=number of poles) different denominators to speed up
        # calculation and avoid sym.limit.  The different denominators are
        # due to shortening of poles after multiplying with (z-z1)**o
        if not (M.is_polynomial(z) and D.is_polynomial(z)):
            print("Numerator or denominator may contain 1/z terms: ", M, D)

        n_poles = len(poles)
        # Leading coefficient of denominator polynom
        a_0 = sym.LC(D, z)
        # The canceled denominator (for each (z-p)**o)
        shorten_denom = {}
        for i in range(n_poles):
            shorten_term = sym.prod([(z - poles[j].expr)**(poles[j].n)
                                     for j in range(n_poles) if j != i], a_0)
            shorten_denom[poles[i].expr] = shorten_term

        # Run through single poles real or complex, order 1 or higher
        for pole in pole_single_dict:

            p = pole

            # Number of occurrences of the pole.
            o = pole_single_dict[pole]

            # X(z)/z*(z-p)**o after shortening.
            expr2 = M / shorten_denom[p]

            if o == 0:
                continue

            if o == 1:
                r = sym.simplify(sym.expand(expr2.subs(z, p)))

                if p == 0:
                    cresult += r * UnitImpulse(n)
                else:
                    uresult += r * p**n
                continue

            # Handle repeated poles.
            all_derivatives = [expr2]
            for i in range(1, o):
                all_derivatives += [sym.diff(all_derivatives[i - 1], z)]

            bino = 1
            sum_p = 0
            for i in range(1, o + 1):
                m = o - i
                derivative = all_derivatives[m]
                # Derivative at z=p
                derivative = sym.expand(derivative.subs(z, p))
                r = sym.simplify(derivative) / sym.factorial(m)

                if p == 0:
                    cresult += r * UnitImpulse(n - i + 1)
                else:
                    sum_p += r * bino * p**(1 - i) / sym.factorial(i - 1)
                    bino *= n - i + 1

            uresult += sym.simplify(sum_p * p**n)

        # Run through complex pole pairs
        for pole in pole_pair_dict:

            p1 = pole[0]
            p2 = pole[1]

            # Number of occurrences of the pole pair
            o1 = pole_pair_dict[pole]
            # X(z)/z*(z-p)**o after shortening
            expr_1 = M / shorten_denom[p1]
            expr_2 = M / shorten_denom[p2]

            # Oscillation parameter
            lam = sym.sqrt(sym.simplify(p1 * p2))
            p1_n = sym.simplify(p1 / lam)
            # term is of form exp(j*arg())
            if len(p1_n.args
                   ) == 1 and p1_n.is_Function and p1_n.func == sym.exp:
                omega_0 = sym.im(p1_n.args[0])
            # term is of form cos() + j sin()
            elif p1_n.is_Add and sym.re(p1_n).is_Function and sym.re(
                    p1_n).func == sym.cos:
                p1_n = p1_n.rewrite(sym.exp)
                omega_0 = sym.im(p1_n.args[0])
            # general form
            else:
                omega_0 = sym.simplify(sym.arg(p1_n))

            if o1 == 1:
                r1 = expr_1.subs(z, p1)
                r2 = expr_2.subs(z, p2)

                r1_re = sym.re(r1).simplify()
                r1_im = sym.im(r1).simplify()

                # if pole pairs is selected, r1=r2*

                # Handle real part
                uresult += 2 * TR9(r1_re) * lam**n * sym.cos(omega_0 * n)
                uresult -= 2 * TR9(r1_im) * lam**n * sym.sin(omega_0 * n)

            else:
                bino = 1
                sum_b = 0
                # Compute first all derivatives needed
                all_derivatives_1 = [expr_1]
                for i in range(1, o1):
                    all_derivatives_1 += [
                        sym.diff(all_derivatives_1[i - 1], z)
                    ]

                # Loop through the binomial series
                for i in range(1, o1 + 1):
                    m = o1 - i

                    # m th derivative at z=p1
                    derivative = all_derivatives_1[m]
                    r1 = derivative.subs(z, p1) / sym.factorial(m)
                    # prefactors
                    prefac = bino * lam**(1 - i) / sym.factorial(i - 1)
                    # simplify r1
                    r1 = r1.rewrite(sym.exp).simplify()
                    # sum
                    sum_b += prefac * r1 * sym.exp(sym.I * omega_0 * (1 - i))
                    # binomial coefficient
                    bino *= n - i + 1

                # take result = lam**n * (sum_b*sum_b*exp(j*omega_0*n) + cc)
                aa = sym.simplify(sym.re(sum_b))
                bb = sym.simplify(sym.im(sum_b))
                uresult += 2 * (aa * sym.cos(omega_0 * n) -
                                bb * sym.sin(omega_0 * n)) * lam**n

        # cresult is a sum of Dirac deltas and its derivatives so is known
        # to be causal.

        return cresult, uresult
Ejemplo n.º 25
0
def ALGO4(As,Bs,Cs,Ds,do_test):
    
    
    
#-------------------STEP 1------------------------------
    if not is_row_proper(As):
        Us,Ast=row_proper(As)
        
    else:
        Us,Ast=eye(As.rows),As
    
    Bst=Us*Bs
    Bst=expand(Bst)
    r=Ast.cols
    #-------------------STEP 2------------------------------
    K=simplify(Ast.inv()*Bst)  #very important 
    Ys=zeros(K.shape)
    for i,j in  product(range(K.rows),range(K.cols)):
        Ys[i,j],q=div(numer(K[i,j]),denom(K[i,j]))       
    
    B_hat=Bst-Ast*Ys
    
    #-------------------END STEP 2------------------------------
    #-------------------STEP 3------------------------------
    Psi=diag(*[[s**( mc.row_degrees(Ast,s)[j]  -i -1) for i in range( mc.row_degrees(Ast,s)[j])] for j in range(r)]).T
    S=diag(*[s**(rho) for rho in mc.row_degrees(Ast,s)])
    Ahr=mc.highest_row_degree_matrix(Ast,s)
    Help=Ast-S*Ahr
    
    SOL={}
    numvar=Psi.rows*Psi.cols
    alr=symbols('a0:%d'%numvar)
    Alr=Matrix(Psi.cols,Psi.rows,alr)
    RHS=Psi*Alr
    for i,j in  product(range(Help.rows),range(Help.cols)):                 #diagonal explain later
        SOL.update(solve_undetermined_coeffs(Eq(Help[i,j],RHS[i,j]),alr,s))
    
    Alr=Alr.subs(SOL)    #substitute(SOL)
    
    
    Aoc=Matrix(BlockDiagMatrix(*[Matrix(rho, rho, lambda i,j: KroneckerDelta(i+1,j))for rho in mc.row_degrees(Ast,s)]))
    Boc=eye(sum(mc.row_degrees(Ast,s)))
    Coc=Matrix(BlockDiagMatrix(*[SparseMatrix(1,rho,{(x,0):1 if x==0 else 0 for x in range(rho)}) for rho in mc.row_degrees(Ast,s)]))

    A0=Aoc-Alr*Ahr.inv()*Matrix(Coc)
    C0=Ahr.inv()*Coc



    SOL={}
    numvar=Psi.cols*Bst.cols
    b0=symbols('b0:%d'%numvar)
    B0=Matrix(Psi.cols,Bst.cols,b0)
    RHS=Psi*B0

    for i,j in  product(range(B_hat.rows),range(B_hat.cols)):                 #diagonal explain later
        SOL.update(solve_undetermined_coeffs(Eq(B_hat[i,j],RHS[i,j]),b0,s))
    B0=B0.subs(SOL)    #substitute(SOL)

    LHS_matrix=simplify(Cs*C0)                                        #left hand side of the equation (1)

    sI_A=s*eye(A0.cols)- A0
    max_degree=mc.find_degree(LHS_matrix,s)                   #get the degree of the matrix at the LHS
                                                  #which is also the maximum degree for the coefficients of Λ(s)
    #---------------------------Creating Matrices Λ(s) and C -------------------------------------

    Lamda=[]
    numvar=((max_degree))*A0.cols
    a=symbols('a0:%d'%numvar)
    for i in range(A0.cols):                                        # paratirisi den douleuei to prin giat;i otra oxi diagonios
        p=sum(a[n +i*(max_degree)]*s**n for n in range(max_degree))  # we want variables one degree lower because we are multiplying by first order monomials
        Lamda.append(p)
        
    Lamda=Matrix(Cs.rows,A0.cols,Lamda)                                #convert the list to Matrix
    
    c=symbols('c0:%d'%(Lamda.rows*Lamda.cols))
    C=Matrix(Lamda.rows,Lamda.cols,c)
    #-----------------------------------------
    
    RHS_matrix=Lamda*sI_A +C                            #right hand side of the equation (1)
     
    '''
    -----------Converting equation (1) to a system of linear -----------
    -----------equations, comparing the coefficients of the  -----------
    -----------polynomials in both sides of the equation (1) -----------
    '''
     EQ=[Eq(LHS_matrix[i,j],expand(RHS_matrix[i,j])) for i,j in product(range(LHS_matrix.rows),range(LHS_matrix.cols)) ]
def ac_analysis(param_d, param_l, instance, file_sufix):
    """ Performs ac analysis

        param_d: substitutions for symbols, or named parameters for plot
        
        param_l: expresions to plot

        format is:
        .ac expresion0 [expresion1 expresion2 ...] sweep = parameter_to_sweep [symmbol_or_option0 = value0
        symmbol_or_option1 = value1 ...]
        
        expresions are on positiona parameters list can hold expresions containing parameters or functions of nodal
        voltages [v(node)] and element and port currents [i(element) isub(port)]

        named parameters (param_d) can contain options for analysis or substitutions for symbols, substituions will be
        done as they are without any parsing, be aware of symbol and option names clashes.

        Config options:
        fstart:         first value of frequency for AC analysis [float]
        fstop:          last value of frequency for AC analysis [float]
        fscale:         scale for frequency points [linear | log]
        npoints:        numbers of points for ac analysis [integer]
        yscale:         scale for y-axis to being displayed on [linear or log]
        hold:           hold plot for next analysis and don't save it to file [yes | no]
        show_poles:     show poles of function on plot [yes | no]
        show_zeroes:    show zeros of function on plot [yes | no]
        title:          display title above ac plot [string]
        show_legend:    show legend on plot [yes | no]
        xkcd:           style plot to be xkcd like scetch
    """
    warnings.filterwarnings('ignore')  # Just getting rid of those fake casting from complex warnings
    s, w = sympy.symbols(('s', 'w'))
    config = {'fstart': 1,
              'fstop': 1e6,
              'fscale': 'log',
              'npoints': 100,
              'yscale': 'log',
              'type': 'amp',
              'hold': 'no',
              'show_poles': 'yes',
              'show_zeros': 'yes',
              'title': None,
              'show_legend': 'no',
              'xkcd': 'no'}

    for config_name in config.keys():
        if config_name in param_d:
            config.update({config_name: param_d[config_name]})
            param_d.pop(config_name)

    subst = []
    for symbol, value in param_d.iteritems():
        tokens = scs_parser.parse_param_expresion(value)
        try:
            value = float(sympy.sympify(scs_parser.params2values(tokens, instance.paramsd),sympy.abc._clash))
        except ValueError:
            raise scs_errors.ScsAnalysisError("Passed subsitution for %s is not a number")

        subst.append((symbol, value))

    if config['fscale'] == 'log':
        fs = np.logspace(np.log10(float(config['fstart'])), np.log10(float(config['fstop'])), int(config['npoints']))
    elif config['fscale'] == 'linear':
        fs = np.linspace(float(config['fstart']), float(config['fstop']), int(config['npoints']))
    else:
        raise scs_errors.ScsAnalysisError(("Option %s for fscale invalid!" % config['yscale']))

    if config['yscale'] != 'log' and config['yscale'] != 'linear':
        raise scs_errors.ScsAnalysisError(("Option %s for yscale invalid!" % config['fscale']))

    filename = "%s.results" % file_sufix

    with open(filename, 'a') as fil:
        if config['xkcd'] == 'yes':
            plt.xkcd()
        plt.hold(True)

        for expresion in param_l:
            fil.write("%s: %s \n---------------------\n" % ('AC analysis of', expresion))
            tokens = scs_parser.parse_analysis_expresion(expresion)
            value0 = sympy.factor(sympy.sympify(scs_parser.results2values(tokens, instance),sympy.abc._clash), s).simplify()
            fil.write("%s = %s \n\n" % (expresion, str(value0)))
            denominator = sympy.denom(value0)
            numerator = sympy.numer(value0)
            poles = sympy.solve(denominator, s)
            zeros = sympy.solve(numerator, s)
            poles_r = sympy.roots(denominator, s)
            zeros_r = sympy.roots(numerator, s)
            gdc = str(value0.subs(s, 0).simplify())
            fil.write('G_DC = %s\n\n' % gdc)

            p = 0
            titled = 1
            for pole, degree in poles_r.iteritems():
                if pole == 0:
                    titled *= s ** degree
                else:
                    titled *= (s / sympy.symbols("\\omega_p%d" % p) + 1)
                p += 1
            z = 0
            titlen = 1
            for zero, degree in zeros_r.iteritems():
                if zero == 0:
                    titlen *= s ** degree
                else:
                    titlen *= (s / sympy.symbols("\\omega_z%d" % z) + 1)
                z += 1
            # title = sympy.symbols("G_DC") * (titlen / titled)
            value = value0.subs(subst)
            f = sympy.symbols('f', real=True)
            value = value.subs(s, sympy.sympify('2*pi*I').evalf() * f)
            tf = sympy.lambdify(f, abs(sympy.numer(value)) / abs(sympy.denom(value)))
            phf = sympy.lambdify(f, sympy.arg(value))

            if config['type'] == 'amp':
                zf = tf
                ylabel = '|T(f)|'
            elif config['type'] == 'phase':
                zf = phf
                ylabel = 'ph(T(f))'
            else:
                raise scs_errors.ScsAnalysisError("Option %s for type invalid!" % config['type'])

            try:
                ys = [float(zf(f)) for f in fs]
            except (ValueError, TypeError):
                raise scs_errors.ScsAnalysisError(
                    "Numeric error while evaluating expresions: %s. Not all values where subsituted?" % value0)

            plt.plot(fs, ys, label=expresion)

            plt.title(r'$%s$' % config['title'] if config['title'] else ' ', y=1.05)
            try:
                plt.xscale(config['fscale'])
                plt.yscale(config['yscale'])
            except ValueError, e:
                raise scs_errors.ScsAnalysisError(e)

            plt.xlabel('f [Hz]')
            plt.ylabel(ylabel)

            if len(poles):
                fil.write('Poles: \n')

            p = 0
            for pole in poles:

                try:
                    pole_value = pole.subs(subst)
                    pole_value_f = abs(np.float64(-abs(pole_value) / sympy.sympify('2*pi').evalf()))
                    pole_s = (-pole).simplify()
                    polestr = str(pole_s)
                    fil.write('wp_%d = %s\n\n' % (p, polestr))

                    p += 1
                    if pole_value_f > float(config['fstop']) \
                            or pole_value_f < float(config['fstart']) \
                            or np.isnan(zf(pole_value_f)):
                        continue
                    if config['show_poles'] == 'yes':
                        pole_label = r'$\omega_{p%d} $' % (p - 1)
                        plt.plot(pole_value_f, zf(pole_value_f), 'o', label=pole_label)
                        plt.text(pole_value_f, zf(pole_value_f), pole_label)
                        plt.axvline(pole_value_f, linestyle='dashed')
                except:
                    pass

            z = 0
            for zero in zeros:
                try:
                    zero_value = zero.subs(subst)
                    zero_value_f = abs(np.float64(-abs(zero_value) / sympy.sympify('2*pi').evalf()))
                    zero_s = (-zero).simplify()
                    zerostr = str(zero_s)
                    fil.write('wz_%d = %s\n\n' % (z, zerostr))
                    z += 1
                    if zero_value_f > float(config['fstop']) \
                            or zero_value_f < float(config['fstart']) \
                            or np.isnan(zf(zero_value_f)):
                        continue
                    if config['show_zeros'] == 'yes':
                        zero_label = r'$\omega_{z%d} $' % (z - 1)
                        plt.plot(zero_value_f, zf(zero_value_f), '*', label=zero_label)
                        plt.axvline(zero_value_f, linestyle='dashed')
                        plt.text(zero_value_f, zf(zero_value_f), zero_label)
                except:
                    pass
            if config['show_legend'] == 'yes':
                plt.legend()
            if config['hold'] == 'no':
                plt.hold(False)
                plt.savefig('%s_%d.png' % (file_sufix, PlotNumber.plot_num))
                plt.clf()
                PlotNumber.plot_num += 1
Ejemplo n.º 27
0
 def solve_u_eqn_rect(self):
     u3_eqn = self.ucubed_dynamic_eqn.subs(theta,sy.pi/2).args[1]
     u2_eqn = sy.simplify(((2*d+w)*(u**2-u3_eqn)).subs(d,Q/(w*u))/u)
     return Eq(u,sy.solve(Eq(sy.numer(u2_eqn)),u)[1])
Ejemplo n.º 28
0

#pdf
A_lp, b_lp, V_lp = lowpass(10000, 10000, 1e-9, 1e-9, 1.586, 1)
Vo_lp = V_lp[3]
hf_lp = lambdify(s, Vo_lp, 'numpy')
bode_output_lp = hf_lp(ss)
plt.loglog(ww, abs(bode_output_lp), lw=2)
plt.title("bode plot of lowpass filter")
plt.xlabel('frequency')
plt.ylabel('H(jw)')
plt.grid(True)
plt.show()

numerator_lp = [
    float(numer(Vo_lp.simplify()).coeff(s, 2)),
    float(numer(Vo_lp.simplify()).coeff(s, 1)),
    float(numer(Vo_lp.simplify()).coeff(s, 0))
]
denominator_lp = [
    float(denom(Vo_lp.simplify()).coeff(s, 2)),
    float(denom(Vo_lp.simplify()).coeff(s, 1)),
    float(denom(Vo_lp.simplify()).coeff(s, 0))
]

#1
v, t = sp.step([numerator_lp, denominator_lp], None, np.arange(0, 1e-3, 1e-6))
plt.plot(v, t)
plt.title("Step response of lowpass filter")
plt.grid(True)
plt.xlabel('t')
def _split_value_equally(delta, count):
  """Splits an integer or rational into roughly equal parts."""
  numer = sympy.numer(delta)
  denom = sympy.denom(delta)
  return [int(math.floor((numer + i) / count)) / denom for i in range(count)]
Ejemplo n.º 30
0
def parametric_differentiation(f,
                               g,
                               dependent_variable,
                               n,
                               simplification_method='None'):
    '''
    Performs differentiation on two parametric equations.
    
    Parameters
    ----------
    f: Sympy Mul
        A Sympy Mul object containing the first parametric equation.
        
    g: Sympy Mul
        A Sympy Mul object containing the second parametric equation.
        
    dependent_variable: Sympy Symbol
        Dependent variable.
    n: integer
        Order of differentiation.
        
    simplification_method: str (or list if method is 'collect'), optional
        Simplification method to be applied to the final answer.
        
    Example
    -------
    >> t = sym.symbols('t')
    >> x = t ** 3 - 3 * t ** 2
    >> y = t ** 4 - 8 * t ** 2
    >> parametric_differentiation(f = x, g = y, 
                                  dependent_variable = t, n = 3)
    
    >> t = sym.symbols('t')
    >> x = sin(t)
    >> y = cos(t)
    >> parametric_differentiation(f = x, g = y, 
                                  dependent_variable = t, n = 2,
                                  simplification_method = 'simplify')
    '''

    t = dependent_variable
    # check that a positive integer
    if np.mod(n, 1) != 0 or n < 0:
        raise ValueError('n must be a positive integer')
    else:
        if n == 1:
            para_derivative = sym.diff(g, t) / sym.diff(f, t)
        else:
            # perform the normal differentiation recurssively
            para_derivative = sym.diff(
                parametric_differentiation(g, f, t, n - 1), t) / sym.diff(
                    f, t)
    numerator, denominator = sym.numer(para_derivative), sym.denom(
        para_derivative)
    # perform simplification according to the simplification method specfied
    if simplification_method == 'None':
        result = sym.factor(numerator) / sym.factor(denominator)
    elif simplification_method == 'simplify':
        result = sym.simplify(numerator) / sym.simplify(denominator)
    elif simplification_method == 'factor':
        result = sym.factor(numerator) / sym.factor(denominator)
    elif simplification_method == 'expand':
        result = sym.expand(numerator) / sym.expand(denominator)
    elif 'collect' in simplification_method:
        # stop and return an error if simplification method is not a list
        if not isinstance(simplification_method, list):
            raise ValueError(
                'Specifiy the simplification_method argument as a list.')
        result = sym.collect(numerator,
                             simplification_method[1]) / sym.collect(
                                 denominator, simplification_method[1])
    elif simplification_method == 'together':
        result = sym.together(numerator) / sym.together(denominator)
    elif simplification_method == 'cancel':
        result = sym.cancel(numerator) / sym.cancel(denominator)
    else:
        raise ValueError(
            "%s is an invalid value for the argument 'simplification_method'" %
            (simplification_method))
    return result
Ejemplo n.º 31
0
def f2nd(function: Basic) -> Tuple[Basic, Basic]:
    function = together(function)
    return numer(function), denom(function)
Ejemplo n.º 32
0
    def define_tanbeta_eqns(self) -> None:
        r"""
        Define equations for surface tilt angle :math:`\beta`.

        Attributes:
            tanbeta_alpha_eqns (list) :
                :math:`\left[ \tan{\left(\beta \right)} \
                = \dfrac{\eta - \sqrt{\eta^{2}
                - 4 \eta \tan^{2}{\left(\alpha \right)} - 2 \eta + 1} - 1}
                {2 \tan{\left(\alpha \right)}},
                \tan{\left(\beta \right)}
                = \dfrac{\eta + \sqrt{\eta^{2}
                - 4 \eta \tan^{2}{\left(\alpha \right)} - 2 \eta + 1} - 1}
                {2 \tan{\left(\alpha \right)}}\right]`

            tanbeta_alpha_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\tan{\left(\beta \right)}
                = \dfrac{\eta - \sqrt{\eta^{2}
                - 4 \eta \tan^{2}{\left(\alpha \right)} - 2 \eta + 1} - 1}
                {2 \tan{\left(\alpha \right)}}`

            tanalpha_ext_eqns (list) :
                :math:`\left[ \tan{\left(\alpha_c \right)}
                = - \frac{\sqrt{\eta - 2 + \frac{1}{\eta}}}{2},
                \tan{\left(\alpha_c \right)}
                = \frac{\sqrt{\eta - 2 + \frac{1}{\eta}}}{2}\right]`

            tanalpha_ext_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\tan{\left(\alpha_c \right)}
                = \dfrac{\eta - 1}{2 \sqrt{\eta}}`

            tanbeta_crit_eqns (list) :
                :math:`\left[ \tan{\left(\beta_c \right)}
                = - \dfrac{\eta - 1}{\sqrt{\eta - 2 + \frac{1}{\eta}}},
                \tan{\left(\beta_c \right)}
                = \dfrac{\eta - 1}{\sqrt{\eta - 2 + \frac{1}{\eta}}}\right]`

            tanbeta_crit_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\tan{\left(\beta_c \right)} = \sqrt{\eta}`

            tanbeta_rdotxz_pz_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\tan{\left(\beta \right)}
                = \dfrac{v^{z} - \frac{1}{p_{z}}}{v^{x}}`

            tanbeta_rdotxz_xiv_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\tan{\left(\beta \right)}
                = \dfrac{\xi^{\downarrow} + v^{z}}{v^{x}}`
        """
        logging.info("gme.core.angles.define_tanbeta_eqns")

        # eta_sub = {eta: self.eta_}

        if self.eta_ == 1 and self.beta_type == "sin":
            logging.info(r"Cannot compute all $\beta$ equations " +
                         r"for $\sin\beta$ model and $\eta=1$")
            return
        solns = solve(self.tanalpha_beta_eqn.subs({tan(alpha): ta}), tan(beta))
        self.tanbeta_alpha_eqns = [
            Eq(tan(beta), soln.subs({ta: tan(alpha)})) for soln in solns
        ]
        # Bit of a hack - extracts the square root term in tan(beta)
        #    as a fn of tan(alpha), which then gives the critical alpha
        root_terms = [[
            arg_ for arg__ in arg_.args if isinstance(arg__, sy.core.power.Pow)
            or isinstance(arg_, sy.core.power.Pow)
        ] for arg_ in numer(self.tanbeta_alpha_eqns[0].rhs).args
                      if isinstance(arg_, (sy.core.mul.Mul, sy.core.power.Pow))
                      ]
        self.tanalpha_ext_eqns = [
            Eq(tan(alpha_ext), soln)
            for soln in solve(Eq(root_terms[0][0], 0), tan(alpha))
        ]

        tac_lt1 = simplify(
            (factor(simplify(self.tanalpha_ext_eqns[0].rhs * sqrt(eta))) /
             sqrt(eta)).subs({Abs(eta - 1): 1 - eta}))
        tac_gt1 = simplify(
            (factor(simplify(self.tanalpha_ext_eqns[1].rhs * sqrt(eta))) /
             sqrt(eta)).subs({Abs(eta - 1): eta - 1}))
        self.tanalpha_ext_eqn = Eq(
            tan(alpha_ext), Piecewise((tac_lt1, eta < 1), (tac_gt1, True)))

        self.tanbeta_crit_eqns = [
            factor(
                tanbeta_alpha_eqn_.subs({
                    beta: beta_crit,
                    alpha: alpha_ext
                }).subs(e2d(tanalpha_ext_eqn_)))
            for tanalpha_ext_eqn_, tanbeta_alpha_eqn_ in zip(
                self.tanalpha_ext_eqns, self.tanbeta_alpha_eqns)
        ]
        # This is a hack, because SymPy simplify can't handle it
        self.tanbeta_crit_eqn = Eq(
            tan(beta_crit), sqrt(simplify((self.tanbeta_crit_eqns[0].rhs)**2)))

        self.tanbeta_rdotxz_pz_eqn = Eq(tan(beta), (rdotz - 1 / pz) / rdotx)

        self.tanbeta_rdotxz_xiv_eqn = self.tanbeta_rdotxz_pz_eqn.subs(
            {pz: self.pz_xiv_eqn.rhs})

        self.tanalpha_ext = float(
            N(self.tanalpha_ext_eqn.rhs.subs({eta: self.eta_})))

        self.tanbeta_crit = float(
            N(self.tanbeta_crit_eqn.rhs.subs({eta: self.eta_})))
Ejemplo n.º 33
0
 def round(self, ndigits=0):
   """Returns a new `Decimal` rounded to this many decimal places."""
   scale = sympy.Integer(10 ** ndigits)
   numer = sympy.numer(self.value) * scale
   denom = sympy.denom(self.value)
   return Decimal(int(round(numer / denom)) / scale)
Ejemplo n.º 34
0
def differential_constants(model, p1, p2, p3):
    """
    Description:
    This function calculates the differential constants u and q necessary to calculate the tip sample interaction
    force.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Parameters:
    :param model:   string
                    Model name, e.g. 'Gen. Kelvin Voigt', 'Gen. Maxwell'
    :param p1:      float
                    Either Ge or Jg
    :param p2:      array of floats
                    Either G or J
    :param pe:      array of floats
                    tau - charactersitic times
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Return, function output:
    retrun:         u:  array of floats
                        differential constants u0, u1, ... un
                    q:  array of floats
                        differential constants q0, q1, ... qn
    """
    s = sym.symbols('s')

    if model == 'Gen. Kelvin-Voigt':
        if len(p2) == len(p3):  # checks J and tau are same lenght
            U = p1 + sum(p2[:] / (1.0 + p3[:] * s))
            U_n = (U).normal()  # writes retardance with common denominator

            u_n = sym.numer(U_n)  # selects the numerator
            u_n = sym.expand(u_n)  # expands each term
            u_n = sym.collect(
                u_n, s)  # collect the terms with the same exponent of s

            q_n = sym.denom(U_n)  # selects the denominator
            q_n = sym.expand(q_n)  # expands each term
            q_n = sym.collect(
                q_n, s)  # collect the terms with the same exponent of s

            q_arr = np.zeros(
                len(p2) +
                1)  # initializes array with lenght J, tau + 1 to store q
            u_arr = np.zeros(
                len(p2) +
                1)  # initializes array with lenght J, tau + 1 to store u

            for i in range(len(p2) + 1):
                q_arr[i] = q_n.coeff(
                    s, i
                )  # selects the terms multiplied by s^n which are synonymus for q0, .., qn
                u_arr[i] = u_n.coeff(
                    s, i
                )  # selects the terms multiplied by s^n which are synonymus for u0, .., un
        else:
            print('input arrays have unequal length')

    if model == 'Gen. Maxwell':
        if len(p2) == len(p3):
            Q = p1 + sum((p2[:] * p3[:]) / (1.0 + p3[:] * s))
            Q_n = (Q).normal()  # writes retardance with common denominator

            u_n = sym.denom(Q_n)  # selects the denominator
            u_n = sym.expand(u_n)  # expands each term
            u_n = sym.collect(
                u_n, s)  # collect the terms with the same exponent of s

            q_n = sym.numer(Q_n)  # selects the numerator
            q_n = sym.expand(q_n)  # expands each term
            q_n = sym.collect(
                q_n, s)  # collect the terms with the same exponent of s

            q_arr = np.zeros(
                len(p2) +
                1)  # initializes array with lenght J, tau + 1 to store q
            u_arr = np.zeros(
                len(p2) +
                1)  # initializes array with lenght J, tau + 1 to store u

            for i in range(len(p2) + 1):
                q_arr[i] = q_n.coeff(
                    s, i
                )  # selects the terms multiplied by s^n which are synonymus for q0, .., qn
                u_arr[i] = u_n.coeff(
                    s, i
                )  # selects the terms multiplied by s^n which are synonymus for u0, .., un
        else:
            print('input arrays have unequal length')

    return u_arr, q_arr
Ejemplo n.º 35
0
 def export(self, x):
     return float(sp.numer(x)) / sp.denom(x)
Ejemplo n.º 36
0
def zeros(G=None, A=None, B=None, C=None, D=None):
    '''
    Return the zeros of a multivariable transfer function system for with
    transfer functions or state-space. For transfer functions, Theorem 4.5
    (p139) is used. For state-space, the method from Equations 4.66 and 4.67
    (p138) is applied.

    Parameters
    ----------
    G : numpy matrix (n x n)
        The transfer function G(s) of the system.
    A, B, C, D : numpy matrix
        State space parameters

    Returns
    -------
    pole : array
        List of poles.

    Example
    -------
    >>> def G(s):
    ...     return 1 / (s + 2) * numpy.matrix([[s - 1,  4],
    ...                                        [4.5, 2 * (s - 1)]])
    >>> zeros(G)
    [4.00000000000000]

    Note
    ----
    Not applicable for a non-squared plant, yet. It is assumed that B,C,D will
    have values if A is defined.
    '''
    # TODO create a beter function to accept paramters and switch between tf and ss

    if not G is None:
        s = sympy.Symbol('s')
        G = sympy.Matrix(G(s))  # convert to sympy matrix object
        det = sympy.simplify(G.det())
        zero = sympy.solve(sympy.numer(det))

    elif not A is None:
        z = sympy.Symbol('z')
        top = numpy.hstack((A, B))
        bot = numpy.hstack((C, D))
        m = numpy.vstack((top, bot))
        M = numpy.matrix(m)
        [rowsA, colsA] = numpy.shape(A)
        [rowsB, colsB] = numpy.shape(B)
        [rowsC, colsC] = numpy.shape(C)
        [rowsD, colsD] = numpy.shape(D)
        p1 = numpy.eye(rowsA)
        p2 = numpy.zeros((rowsB, colsB))
        p3 = numpy.zeros((rowsC, colsC))
        p4 = numpy.zeros((rowsD, colsD))
        top = numpy.hstack((p1, p2))
        bot = numpy.hstack((p3, p4))
        p = numpy.vstack((top, bot))
        Ig = sympy.Matrix(p)
        zIg = z * Ig
        f = zIg - M
        zf = f.det()
        zero = sympy.solve(zf, z)

    return zero
Ejemplo n.º 37
0
def apart_fact(Fs):
    S=0
    Ls = apart(Fs).as_ordered_terms()
    for l in Ls:
        S += numer(l)/factor(denom(l))
    return expand_mul(S)
Ejemplo n.º 38
0
    def define_px_poly_eqn(
        self, eta_choice: Rational = None, do_ndim: bool = False
    ) -> None:
        r"""
        Define :math:`p_x` polynomial.

        TODO: remove ref to xiv_0

        Define polynomial form of function combining normal-slowness
        covector components :math:`(p_x,p_z)`
        (where the latter is given in terms of the vertical erosion rate
        :math:`\xi^{\downarrow} = -\dfrac{1}{p_z}`)
        and the erosion model flow component :math:`\varphi(\mathbf{r})`

        Args:
            eta_choice (:class:`~sympy.core.numbers.Rational`):
                value of :math:`\eta` to use instead value given at
                instantiation; otherwise the latter value is used

        Attributes:
            poly_px_xiv_varphi_eqn (:class:`~sympy.polys.polytools.Poly`):
                :math:`\operatorname{Poly}{\left(
                \left(\xi^{\downarrow}\right)^{4}
                \varphi^{4}{\left(\mathbf{r} \right)} p_{x}^{6}
                -  \left(\xi^{\downarrow}\right)^{4} p_{x}^{2}
                -  \left(\xi^{\downarrow}\right)^{2}, p_{x},
                domain=\mathbb{Z}\left[\varphi{\left(\mathbf{r} \right)},
                \xi^{\downarrow}\right] \right)}`

            poly_px_xiv_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\varphi_0^{4}
                \left(\xi^{\downarrow{0}}\right)^{4} p_{x}^{6}
                \left(\varepsilon
                + \left(\frac{x_{1} - {r}^x}{x_{1}}\right)^{2 \mu}\right)^{4}
                - \left(\xi^{\downarrow{0}}\right)^{4} p_{x}^{2}
                - \left(\xi^{\downarrow{0}}\right)^{2} = 0`
        """
        logging.info(f"gme.core.pxpoly.define_px_poly_eqn (ndim={do_ndim})")
        if do_ndim:
            # Non-dimensionalized version
            varphi0_solns = solve(
                self.sinCi_xih0_eqn.subs({eta: eta_choice}), varphi_0
            )
            varphi0_eqn = Eq(varphi_0, varphi0_solns[0])
            if eta_choice is not None and eta_choice <= 1:
                tmp_eqn = separatevars(
                    simplify(
                        self.px_xiv_varphi_eqn.subs({eta: eta_choice})
                        .subs({varphi_r(rvec): self.varphi_rxhat_eqn.rhs})
                        .subs(e2d(self.px_pxhat_eqn))
                        .subs(e2d(varphi0_eqn))
                    )
                )
                self.poly_pxhat_xiv_eqn = simplify(
                    Eq(
                        (
                            numer(tmp_eqn.lhs)
                            - denom(tmp_eqn.lhs) * (tmp_eqn.rhs)
                        )
                        / xiv ** 2,
                        0,
                    )
                )
                self.poly_pxhat_xiv0_eqn = self.poly_pxhat_xiv_eqn.subs(
                    {xiv: xiv_0}
                ).subs(e2d(self.xiv0_xih0_Ci_eqn))
            else:
                tmp_eqn = separatevars(
                    simplify(
                        self.px_xiv_varphi_eqn.subs({eta: eta_choice})
                        .subs({varphi_r(rvec): self.varphi_rxhat_eqn.rhs})
                        .subs(e2d(self.px_pxhat_eqn))
                        .subs(e2d(varphi0_eqn))
                    )
                )
                self.poly_pxhat_xiv_eqn = simplify(
                    Eq(
                        (
                            numer(tmp_eqn.lhs)
                            - denom(tmp_eqn.lhs) * (tmp_eqn.rhs)
                        )
                        / xiv ** 2,
                        0,
                    )
                )
                self.poly_pxhat_xiv0_eqn = simplify(
                    Eq(
                        self.poly_pxhat_xiv_eqn.lhs.subs({xiv: xiv_0}).subs(
                            e2d(self.xiv0_xih0_Ci_eqn)
                        )
                        / xih_0 ** 2,
                        0,
                    )
                )
        else:
            # Dimensioned version
            tmp_eqn = simplify(self.px_xiv_varphi_eqn.subs({eta: eta_choice}))
            if eta_choice is not None and eta_choice <= 1:
                self.poly_px_xiv_varphi_eqn = poly(tmp_eqn.lhs, px)
            else:
                self.poly_px_xiv_varphi_eqn = poly(
                    numer(tmp_eqn.lhs) - denom(tmp_eqn.lhs) * (tmp_eqn.rhs), px
                )
            self.poly_px_xiv_eqn = Eq(
                self.poly_px_xiv_varphi_eqn.subs(e2d(self.varphi_rx_eqn)), 0
            )
Ejemplo n.º 39
0
    def prep_geodesic_eqns(self, parameters: Dict = None):
        r"""
        Define geodesic equations.

        Args:
            parameters:
                dictionary of model parameter values to be used for
                equation substitutions

        Attributes:
            gstar_ij_tanbeta_mat (`Matrix`_):
                :math:`\dots`

            g_ij_tanbeta_mat (`Matrix`_):
                :math:`\dots`

            tanbeta_poly_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\dots` where :math:`a := \tan\alpha`

            tanbeta_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\tan{\left(\beta \right)} = \dots` where
                :math:`a := \tan\alpha`

            gstar_ij_tanalpha_mat (`Matrix`_):
                a symmetric tensor with components (using shorthand
                :math:`a := \tan\alpha`)

                :math:`g^*[1,1] = \dots`

                :math:`g^*[1,2] = g^*[2,1] = \dots`

                :math:`g^*[2,2] = \dots`

            gstar_ij_mat (`Matrix`_):
                a symmetric tensor with components
                (using shorthand :math:`a := \tan\alpha`, and with a
                particular choice of model parameters)

                :math:`g^*[1,1] = \dots`

                :math:`g^*[1,2] = g^*[2,1] = \dots`

                :math:`g^*[2,2] =  \dots`

            g_ij_tanalpha_mat (`Matrix`_):
                a symmetric tensor with components (using shorthand
                :math:`a := \tan\alpha`)

                :math:`g[1,1] = \dots`

                :math:`g[1,2] = g[2,1] = \dots`

                :math:`g[2,2] = \dots`

            g_ij_mat (`Matrix`_):
                a symmetric tensor with components
                (using shorthand :math:`a := \tan\alpha`, and with a
                particular choice of model parameters)

                :math:`g[1,1] =\dots`

                :math:`g[1,2] = g[2,1] = \dots`

                :math:`g[2,2] = \dots`

            g_ij_mat_lambdified   (function) :
                lambdified version of `g_ij_mat`

            gstar_ij_mat_lambdified (function) :
                lambdified version of `gstar_ij_mat`
        """
        logging.info("gme.core.geodesic.prep_geodesic_eqns")
        self.gstar_ij_tanbeta_mat = None
        self.g_ij_tanbeta_mat = None
        self.tanbeta_poly_eqn = None
        self.tanbeta_eqn = None
        self.gstar_ij_tanalpha_mat = None
        self.gstar_ij_mat = None
        self.g_ij_tanalpha_mat = None
        self.g_ij_mat = None
        self.g_ij_mat_lambdified = None
        self.gstar_ij_mat_lambdified = None

        mu_eta_sub = {mu: self.mu_, eta: self.eta_}

        # if parameters is None: return
        H_ = self.H_eqn.rhs.subs(mu_eta_sub)

        # Assume indexing here ranges in [1,2]
        def p_i_lambda(i):
            return [px, pz][i - 1]

        # r_i_lambda = lambda i: [rx, rz][i-1]
        # rdot_i_lambda = lambda i: [rdotx, rdotz][i-1]

        def gstar_ij_lambda(i, j):
            return simplify(
                Rational(2, 2) * diff(diff(H_, p_i_lambda(i)), p_i_lambda(j)))

        gstar_ij_mat = Matrix([
            [gstar_ij_lambda(1, 1),
             gstar_ij_lambda(2, 1)],
            [gstar_ij_lambda(1, 2),
             gstar_ij_lambda(2, 2)],
        ])
        gstar_ij_pxpz_mat = gstar_ij_mat.subs({varphi_r(rvec): varphi})
        g_ij_pxpz_mat = gstar_ij_mat.inv().subs({varphi_r(rvec): varphi})

        cosbeta_eqn = Eq(cos(beta), 1 / sqrt(1 + tan(beta)**2))
        sinbeta_eqn = Eq(sin(beta), sqrt(1 - 1 / (1 + tan(beta)**2)))
        sintwobeta_eqn = Eq(sin(2 * beta), cos(beta)**2 - sin(beta)**2)

        self.gstar_ij_tanbeta_mat = expand_trig(
            simplify(gstar_ij_pxpz_mat.subs(e2d(
                self.px_pz_tanbeta_eqn)))).subs(e2d(cosbeta_eqn))
        self.g_ij_tanbeta_mat = expand_trig(
            simplify(g_ij_pxpz_mat.subs(e2d(self.px_pz_tanbeta_eqn)))).subs(
                e2d(cosbeta_eqn))

        tanalpha_beta_eqn = self.tanalpha_beta_eqn.subs(mu_eta_sub)
        tanbeta_poly_eqn = Eq(
            numer(tanalpha_beta_eqn.rhs) -
            tanalpha_beta_eqn.lhs * denom(tanalpha_beta_eqn.rhs),
            0,
        ).subs({tan(alpha): ta})

        tanbeta_eqn = Eq(tan(beta), solve(tanbeta_poly_eqn, tan(beta))[0])
        self.tanbeta_poly_eqn = tanbeta_poly_eqn
        self.tanbeta_eqn = tanbeta_eqn

        # Replace all refs to beta with refs to alpha
        self.gstar_ij_tanalpha_mat = (self.gstar_ij_tanbeta_mat.subs(
            e2d(sintwobeta_eqn)).subs(e2d(sinbeta_eqn)).subs(
                e2d(cosbeta_eqn)).subs(e2d(tanbeta_eqn))).subs(mu_eta_sub)
        self.gstar_ij_mat = (self.gstar_ij_tanalpha_mat.subs({
            ta: tan(alpha)
        }).subs(e2d(self.tanalpha_rdot_eqn)).subs(
            e2d(self.varphi_rx_eqn.subs(
                {varphi_r(rvec): varphi}))).subs(parameters)).subs(mu_eta_sub)
        self.g_ij_tanalpha_mat = (expand_trig(self.g_ij_tanbeta_mat).subs(
            e2d(sintwobeta_eqn)).subs(e2d(sinbeta_eqn)).subs(
                e2d(cosbeta_eqn)).subs(e2d(tanbeta_eqn))).subs(mu_eta_sub)
        self.g_ij_mat = (self.g_ij_tanalpha_mat.subs({
            ta: rdotz / rdotx
        }).subs(e2d(self.varphi_rx_eqn.subs(
            {varphi_r(rvec): varphi}))).subs(parameters)).subs(mu_eta_sub)
        self.g_ij_mat_lambdified = lambdify((rx, rdotx, rdotz, varepsilon),
                                            self.g_ij_mat, "numpy")
        self.gstar_ij_mat_lambdified = lambdify((rx, rdotx, rdotz, varepsilon),
                                                self.gstar_ij_mat, "numpy")
# importar libreria matemática simbólica
import sympy as sp

# Numeros y variables
sp.numer(numero)  # Numero
sp.Symbol('numero')  # Numero
sp.Symbol('nombre_constante')  # Constante
sp.Symbol('nombre_variable')  # Variable
sp.Rational(num1, num2)  # Numero racional

# Construcción de expresiones con numeros y varaibles
x = sp.Symbol('x')
y = sp.Symbol('y')
-x  # Inverso
x + y  # Suma
x - y  # Resta
x * y  # Multiplicación
x / y  # División
x**y  # Potencia

# Operación de expresiones
sp.expand(expresión)  # Expandir expresión
sp.simplify(expresión)  # Simplificar expresión
sp.factor(expresión)  # Factorizar expresión
sp.N(expresión)  # Resolver expresión
expresión.evalf()  # Resolver expresión
sp.solve(
    expresión, variable
)  # Solucionar ecuación igualada a 0 (Pueden ser ecuaciones trasendentales)
sp.solve(
    [exp1, exp2, expN], [var1, var2, varN]
Ejemplo n.º 41
0
def symmetryDetection(allVariables, diffEquations, observables, obsFunctions, initFunctions,
						predictions, predFunctions, ansatz = 'uni', pMax = 2, inputs = [], 
						fixed = [], parallel = 1, allTrafos = False, timeTrans = False,
						pretty = True, suffix=''):
	
	n = len(allVariables)
	m = len(diffEquations)
	h = len(observables)

	###########################################################################################
	#############################     prepare equations    ####################################
	###########################################################################################
	sys.stdout.write('Preparing equations...')
	sys.stdout.flush()

	# make infinitesimal ansatz
	infis, diffInfis, rs = makeAnsatz(ansatz, allVariables, m, len(inputs), pMax, fixed)

	# get infinitesimals of time transformation
	if timeTrans:
		rs.append(spy.var('r_T_1'))
		diffInfiT = rs[-1]
		allVariables += [T]
	else:
		diffInfiT = None

	# and convert to polynomial
	infis, diffInfis = transformInfisToPoly(infis, diffInfis, allVariables, rs, parallel, ansatz)
	
	diffInfiT = Apoly(diffInfiT, allVariables, rs)

	### extract numerator and denominator of equations
	#differential equations
	numerators = [0]*m
	denominators = [0]*m
	for k in range(m):
		rational = spy.together(diffEquations[k])
		numerators[k] = Apoly(spy.numer(rational), allVariables, None)
		denominators[k] = Apoly(spy.denom(rational), allVariables, None)

	#observation functions
	obsNumerators = [0]*h
	obsDenominatros = [0]*h
	for k in range(h):
		rational = spy.together(obsFunctions[k])
		obsNumerators[k] = Apoly(spy.numer(rational), allVariables, None)
		obsDenominatros[k] = Apoly(spy.denom(rational), allVariables, None)

	#initial functions
	if len(initFunctions) != 0:
		initNumerators = [0]*m
		initDenominatros = [0]*m
		for k in range(m):
			rational = spy.together(initFunctions[k])
			initNumerators[k] = Apoly(spy.numer(rational), allVariables, None)
			initDenominatros[k] = Apoly(spy.denom(rational), allVariables, None)
	else:
		initNumerators = []
		initDenominatros = []

	### calculate numerator of derivatives of equations
	#differential equatioins
	derivativesNum = [0]*m
	for i in range(m):
		derivativesNum[i] = [0]*n
	for k in range(m):
		for l in range(n):
			derivativesNum[k][l] = Apoly(None, allVariables, None)
			derivativesNum[k][l].add(numerators[k].diff(l).mul(denominators[k]))
			derivativesNum[k][l].sub(numerators[k].mul(denominators[k].diff(l)))

	#observation functions
	obsDerivativesNum = [0]*h
	for i in range(h):
		obsDerivativesNum[i] = [0]*n
	for k in range(h):
		for l in range(n):
			obsDerivativesNum[k][l] = Apoly(None, allVariables, None)
			obsDerivativesNum[k][l].add(obsNumerators[k].diff(l).mul(obsDenominatros[k]))
			obsDerivativesNum[k][l].sub(obsNumerators[k].mul(obsDenominatros[k].diff(l)))

	#initial functions
	if len(initFunctions) != 0:
		initDerivativesNum = [0]*len(initFunctions)
		for i in range(m):
			initDerivativesNum[i] = [0]*n
		for k in range(m):
			for l in range(n):
				initDerivativesNum[k][l] = Apoly(None, allVariables, None)
				initDerivativesNum[k][l].add(initNumerators[k].diff(l).mul(initDenominatros[k]))
				initDerivativesNum[k][l].sub(initNumerators[k].mul(initDenominatros[k].diff(l)))
	else:
		initDerivativesNum = []

	sys.stdout.write('\rPreparing equations...done\n')
	sys.stdout.flush()

	###########################################################################################
	############################     build linear system    ###################################
	###########################################################################################
	sys.stdout.write('\nBuilding system...')
	sys.stdout.flush()

	rSystem = buildSystem(numerators, denominators, derivativesNum, obsDerivativesNum,
				initDenominatros, initDerivativesNum, initFunctions, 
				infis, diffInfis, diffInfiT, allVariables, rs, parallel, ansatz)

	sys.stdout.write('done\n')
	sys.stdout.flush()

	
	###########################################################################################
	##############################     solve system    ########################################
	###########################################################################################
	sys.stdout.write('\nSolving system of size ' + str(rSystem.shape[0]) + 'x' +\
						str(rSystem.shape[1]) + '...')
	sys.stdout.flush()

	#get LU decomposition from scipy
	rSystem = scipy.linalg.lu(rSystem, permute_l=True)[1]

	#calculate reduced row echelon form
	rSystem, pivots = getrref(rSystem)

	sys.stdout.write('done\n')
	sys.stdout.flush()

	###########################################################################################
	#############################     process results    ######################################
	###########################################################################################
	sys.stdout.write('\nProcessing results...')
	sys.stdout.flush()

	# calculate solution space
	sys.stdout.write('\n  calculating solution space')
	sys.stdout.flush()
	baseMatrix = nullSpace(rSystem, pivots)

	#substitute solutions into infinitesimals
	#(and remove the ones with common parameter factors)
	sys.stdout.write('\n  substituting solutions')
	sys.stdout.flush()
	infisAll = []
	for l in range(baseMatrix.shape[1]):
		infisTmp = [0]*n
		for i in range(len(infis)):
			infisTmp[i] = infis[i].getCopy()
			infisTmp[i].rs = baseMatrix[:,l]
			infisTmp[i] = infisTmp[i].as_expr()
		if timeTrans:
			infisTmp.append(baseMatrix[-1,l] * T)

		if allTrafos:
			infisAll.append(infisTmp)
		else:
			if not checkForCommonFactor(infisTmp, allVariables, m):
				infisAll.append(infisTmp)
			
	print('')
	sys.stdout.write('done\n')
	sys.stdout.flush()

	# print transformations
	print('\n\n')
	if len(infisAll) != 0: printTransformations(infisAll, allVariables, pretty,suffix)

	###########################################################################################
	############################     check predictions    #####################################
	###########################################################################################
	if predictions != False:
		checkPredictions(predictions, predFunctions, infisAll, allVariables)

	print(time.strftime('\nTotal time: %Hh:%Mm:%Ss', time.gmtime(time.time()-t0)))
Ejemplo n.º 42
0
res_freq = 1 / s.sqrt(Ls * Cs)
imp_at_approx_res = s.simplify(Z.subs(o, res_freq))
imp_at_approx_res

# Note that this is a decent thing to do, since we are at least somewhat close to resonance, and we're getting an idea of what our impedance is like near resonance:

s.re(imp_at_approx_res).simplify()

# So, as we expect, the $C_{ratio}$ does allow us to adjust the real part of our impedance (so we can target 50 $\Omega$), but the value we want will depend very strongly on the built-in resistances in the circuit, which we don't really control.

Cn = s.symbols('C_{new}', positive=True, real=True)

# Cn = (Cr+1)/Cs

s.numer(s.im(Z).subs(Cr, Cn * Cs - 1).simplify())

# ### One ratio per tune
# Finally, I give the impedance in terms of the ratio and the tune capacitance

Z = -1j / o / Cm + Rm + 1 / (1 / (1j * o * Ls + Rt) + 1 / (-1j / Ct / o + Rt))
Z = Z.subs(Cm, Cr * Ct).simplify()
Z

# We can solve to find that there is only one ratio that will allow us to tune -- again, this depends not only on the inductance, frequency, and tuning capacitance, but also on the resistance in the tuning circuit

soln = s.solve(s.Eq(s.im(Z).simplify(), 0), Cr)
assert len(soln) == 1
soln = soln[0]
soln