# SLiCAPmath.py

SLiCAP module with math functions.

DIN_A(f_0=1000)

  Returns DIN_A frequency weighting function (audio), normalized at f=f_0

  See WiKi R_A(f): https://en.wikipedia.org/wiki/A-weighting

  Parameters:

    f_0 (float, int, sympy.Symbol) – Normalization frequency (frequency at which the weight = 1), defaults to 1kHz

  Returns:

    R_A(f): Weighting function, argument = ini.frequency

  Return type:

    sympy.Expr

ENG(number, scaleFactors=False)

  Converts a number into a tuple with a number and exponent as power of 3 or as scale factor.

  Parameters:

    - number – Anything representing a number

    - scaleFactors (Bool) – if ‘True’, scale factors ‘y’, ‘z’, ‘a’, ‘f’, ‘p’, ‘n’, ‘u’, ‘m’, ‘k’, ‘M’, ‘G’, ‘T’, and ‘P’ will be returned instead of exponents -24, -21, -18, -15, -12, -9, -6, -3, 3, 6, 9, 12, and 15, respectively.

  Returns:

    number, exp

  Return type:

    tuple:

    - number: int, float, or input type if conversion failed

    - exp: int, str (in case of scaleFactors == True), or None, if conversion failed

  Example:

      >>> import SLiCAP as sl
      >>> import sympy as sp

      >>> sl.ini.disp # number of significant digits to be diplayed
          4

      >>> sl.ENG(sp.sqrt(sp.pi))
          (1.772, 0)

      >>> sl.ENG(1234567890)
          (1.234, 9)

      >>> sl.ENG(1234567890, scaleFactors=True)
          (1.234, 'G')

      >>> sl.ENG(1.234567890E-4)
          (123.4, -6)

      >>> sl.ENG(1.234567890E-4, scaleFactors=True)
          (123.4, 'u')

PdBm2V(p, r)

  Returns the RMS value of the voltage that generates p dBm power in a resistor with resistance r.

  Parameters:

    - p (sympy.Symbol, sympy.Expression, int, or float) – Power in dBm

    - r (sympy.Symbol, sympy.Expression, int, or float) – Resistance

  Returns:

    voltage

  Return type:

    sympy.Expression

assumePosParams(expr, params='all')

  Returns the sympy expression ‘expr’ in which variables, except the Laplace variable, have been redefined as positive.

  Parameters:

    - expr (sympy.Expr, sympy.Symbol) – Sympy expression

    - params (list, str) – List with variable names (str), or ‘all’ or a variable name (str).

  Returns:

    Expression with redefined variables.

  Return type:

    sympy.Expr, sympy.Symbol

assumeRealParams(expr, params='all')

  Returns the sympy expression ‘expr’ in which variables, except the Laplace variable, have been redefined as real.

  Parameters:

    - expr (sympy.Expr, sympy.Symbol) – Sympy expression

    - params (list, str) – List with variable names (str), or ‘all’ or a variable name (str).

  Returns:

    Expression with redefined variables.

  Return type:

    sympy.Expr, sympy.Symbol

besselPoly(n)

  Returns a normalized Bessel polynomial of the n-th order of the Laplace variable.

  Zero-frequency value = 1, -3dB frequency (magnitude = 2) is 1 rad/s.

  Parameters:

    n (int) – order

  Returns:

    Bessel polynomial of the n-th order of the Laplace variable

  Return type:

    sympy.Expression

butterworthPoly(n)

  Returns a narmalized Butterworth polynomial of the n-th order of the Laplace variable.

  Zero-frequency value = 1, -3dB frequency (magnitude = 2) is 1 rad/s.

  Parameters:

    n (int) – order

  Returns:

    Butterworth polynomial of the n-th order of the Laplace variable

  Return type:

    sympy.Expression

chebyshev1Poly(n, ripple)

  Returns a normalized Chebyshev polynomial of the n-th order of the Laplace variable, with a ripple of <ripple> dB

  Zero-frequency value = 1, -3dB frequency (magnitude = 2) is 1 rad/s.

  Parameters:

    n (int) – order

  Returns:

    Chebyshev polynomial of the n-th order of the Laplace variable

  Return type:

    sympy.Expression

clearAssumptions(expr, params='all')

  Returns the sympy expression ‘expr’ in which the assumtions ‘Real’ and ‘Positive’ have been deleted.

  Parameters:

    - expr (sympy.Expr, sympy.Symbol) – Sympy expression

    - params (list, str) – List with variable names (str), or ‘all’ or a variable name (str).

  Returns:

    Expression with redefined variables.

  Return type:

    sympy.Expr, sympy.Symbol

coeffsTransfer(rational, var=s, method='lowest')

  Returns a nested list with the coefficients of the variable of the numerator and of the denominator of ‘rational’.

  The coefficients are in ascending order.

  Parameters:

    - rational (sympy.Expr) – Rational function of the variable.

    - variable (sympy.Symbol) – Variable of the rational function

    - method (str) –

      Normalization method:

      - ”highest”: the coefficients of the highest order of <variable> of the denominator will be noramalized to unity.

      - ”lowest”: the coefficients of the lowest order of <variable> of the denominator will be noramalized to unity.

  Returns:

    Tuple with gain and two lists: [gain, numerCoeffs, denomCoeffs]

    1. gain (sympy.Expr): ratio of the nonzero coefficient of the lowest order of the numerator and the coefficient of the nonzero coefficient of the lowest order of the denominator.

    2. numerCoeffs (list): List with all coeffcients of the numerator in ascending order.

    3. denomCoeffs (list): List with all coeffcients of the denominator in ascending order.

  Return type:

    tuple

det(M, method='ME')

  Returns the determinant of a square matrix ‘M’ calculated using recursive minor expansion (Laplace expansion). For large matrices with symbolic entries, this is faster than the built-in sympy.Matrix.det() method.

  Parameters:

    - M (sympy.Matrix) – Sympy matrix

    - method –

      Method used:

      - ME: SLiCAP Minor expansion

      - BS: SLiCAP Bareis fraction-free expansion

      - FC: SLiCAP Frequency Constants method

      - LU: Sympy built-in LU method

      - bareis: Sympy built-in Bareis method

  Returns:

    Determinant of ‘M’

  Return type:

    sympy.Expr

doCDS(result, tau)

  Returns a copy of the noise execution result with all onoise results in it multiplied with (2*sin(pi*ini.frequency*tau))^2, and deleted inoise results.

  Parameters:

    - result (sympy.instruction) – sympy instruction object

    - tau (sympy.Expr, sympy.Symbol, int or float) – Time between two samples

  Returns:

    sympy instruction object

  Return type:

    sympy.instruction

equateCoeffs(protoType, transfer, noSolve=[], numeric=True)

  Returns the solutions of the equation transferFunction = protoTypeFunction.

  Both transfer and prototype should be Laplace rational functions. Their numerators should be polynomials of the Laplace variable of equal order and their denominators should be polynomials of the Laplace variable of equal order.

  Parameters:

    - protoType (sympy.Expr) – Prototype rational expression of the Laplace variable

    - transfer

  Transfer fucntion of which the parameters need to be solved. The numerator and the denominator of this rational expression should be of the same order as those of the prototype.

  Parameters:

    - noSolve (list) – List with variables (str, sympy.core.symbol.Symbol) that do not need to be solved. These parameters will remain symbolic in the solutions.

    - numeric (bool) – True will convert numeric results with floats instead of rationals

  Returns:

    Dictionary with key-value pairs:

    - key: name of the parameter (sympy.core.symbol.Symbol)

    - value: solution of this parameter: (sympy.Expr, int, float)

  Return type:

    dict

filterFunc(f_char, f_type, f_order, f_low=None, f_high=None, ripple=1)

  Returns a f_type prototype function based on a f_char polynomial:

  - f_char = butterworth

  - f_char = bessel

  - f_char = chebyshev1 # Chebyshev type 1 (passband ripple)

  - f_type = lp : low-pass, requires f_high

  - f_type = hp : high-pass, requires f_low

  - f_type = bp : band-pass, requires f_low and f_high

  - f_type = bs : band-stop, requires f_low and f_high

  - f_type = ap : all-pass, requires f_high

  Parameters:

    - f_char (str) – filter characteristic: Butterworth or Bessel

    - f_type (str) – filter type: lp, hp, bp, bs, ap

    - f_order (str, int) – order of the filter

    - f_low (sympy.Symbol, float, int) – low-frequency -3dB corner [Hz]

    - f_high (sympy.Symbol, float, int) – high-frequency -3dB corner [Hz]

    - ripple (int, float) – pass-band ripple in [dB]

  Returns:

    Filter prototype function (Laplace Transform)

  Return type:

    sympy.Expr

findServoBandwidth(loopgainRational)

  Determines the intersection points of the asymptotes of the magnitude of the loopgain with unity.

  Parameters:

    loopgainRational – Rational function of the Laplace variable, that represents the loop gain of a circuit.

  Returns:

    Dictionary with key-value pairs:

    - hpf: frequency of high-pass intersection

    - hpo: order at high-pass intersection

    - lpf: frequency of low-pass intersection

    - lpo: order at low-pass intersection

    - mbv: mid-band value of the loopgain (highest value at order = zero)

    - mbf: lowest freqency of mbv

  Return type:

    dict

float2rational(expr)

  Converts floats in expr into rational numbers.

  Parameters:

    expr (sympy.Expression) – Sympy expression in which floats need to be converterd into rational numbers.

  Returns:

    expression in which floats have been replaced with rational numbers.

  Return type:

    sympy.Expression

fullSubs(valExpr, parDefs)

  Returns ‘valExpr’ after all parameters of ‘parDefs’ have been substituted into it recursively until no changes occur, or until the maximum number of substitutions is achieved.

  The maximum number opf recursive substitutions is set by ini.maxRexSubst.

  Parameters:

    - valExpr (sympy.Expr, sympy.Symbol, int, float) – Eympy expression in which the parameters should be substituted.

    - parDefs –

      Dictionary with key-value pairs:

      - key (sympy.Symbol): parameter name

      - value (sympy object, int, float): value of the parameter

  Returns:

    Expression or value obtained from recursive substitutions of parameter definitions into ‘valExpr’.

  Return type:

    sympy object, int, float

ilt(expr, s, t, integrate=False)

  Returns the Inverse Laplace Transform f(t) of an expression F(s) for t > 0.

  Parameters:

    - expr (Sympy expression, integer, float, or str.) – Function of the Laplace variable F(s).

    - s (sympy.Symbol) – Laplace variable

    - t (sympy.Symbol) – time variable

    - integrate (Bool) – True multiplies expr with 1/s, defaults to False

  Returns:

    Inverse Laplace Transform f(t)

  Return type:

    sympy.Expr

integrate_monomial_coeffs(expr, variables, x, x_lower, x_upper, doit=True, wf=1, method='auto', CDS=False, tau=None, points=1000, numeric=True)

  Returns expr in which x in coefficients of monomials of variables are integrated over the range x_lower … x_upper. If doit=True the integration will be performed, else integral operators will be returned.

  Parameters:

    - expr – Sympy expression

    - variables (list with sympy.Symbol objects) – List or tuple with variables (currently only two variables accepted)

    - x (sympy.Symbol) – integration variable

    - x_lower (sympy.Symbol, int or float) – start value integration

    - x_upper (sympy.Symbol, int or float) – end value integration

    - doit (bool) – True/False; If True, the integration will be performed, else integral operators will be returned.

    - CDS (Bool) – True if correlated double sampling is required, defaults to False If True parameter ‘tau’ must be given a nonzero finite value (can be symbolic). If method==”log” a logarithmic frequency seep will be used from the lowest frequency until the frequency of the first notch: f=1/tau. Linear sweeping will be used for all other frequency segments. The number of points per segment will be set to points. If type(points) == list, the method will be set to ‘scipy’.

    - tau (str, int, float, sp.Symbol) – CDS delay time

    - method (str) –

      Integration method, implemented methods are:

      - ”auto”: automatic selection of integration method

      - ”symbolic”: forces symbolic integration

      - ”scipy”: numeric integration using scipy.integrate.quad

          CDS will use integration per section f=1/tau

      - ”log”: numeric integration using numpy.trapezoid with a

          logarithmic frequency sweep from f_min to f_max and the number of points (CDS: per section) set by points

      - ”lin”: numeric integration using numpy.trapezoid with a

          linear frequency sweep from fmin to fmax and the number of points (CDS: per section) set by points

      - ”list”: numeric integration using numpy.trapezoid with frequency

          points taken from points (CDS: switches method to ‘scipy’).

      Defaults to ‘auto’

    - points (int, list) – Number of frequency points for integration for method=”lin” and method=”log”, or a list with points. Defaults to 0. If type(points) == list f_min, and f_max will be ignored.

    - numeric (Bool) – If True the result will be converted to numeric. Defaults to True

  Returns:

    Integration result

  Return type:

    sympy.expr, int or float

integrated_monomial_coeffs(expr, variables, x, x_lower, x_upper, doit=True, wf=1, method='auto', CDS=False, tau=None, points=1000, numeric=True)

  Returns a dictionary with key-value pairs:

  - key: monomial of variables

  - coefficient of this monomial with x integrated over the range x_lower … x_upper.

  If doit=True the integration will be performed, else integral operators will be returned.

  Parameters:

    - expr – Sympy expression

    - variables (list with sympy.Symbol objects) – List or tuple with variables (currently only two variables accepted)

    - x (sympy.Symbol) – integration variable

    - x_lower (sympy.Symbol, int or float) – start value integration

    - x_upper (sympy.Symbol, int or float) – end value integration

    - doit (bool) – True/False; If True, the integration will be performed, else integral operators will be returned.

  Returns:

    Dictionary with key-value pairs:

    - key (sympy.Expr): monomial

    - value (sympy.Expr): integrated monomial coefficient

  Return type:

    sympy.expr, int or float

listPZ(pzResult)

  Prints lists with numeric poles and zeros.

  Parameters:

    pzResult (SLiCAPinstruction.instruction) – SLiCAP execution results of pole-zero analysis.

  Returns:

    None

  Return type:

    NoneType

nonPolyCoeffs(expr, var)

  Returns a dictionary with coefficients of negative and positive powers of var.

  Parameters:

    var (sympy.Symbol) – Variable of which the coefficients will be returned

  Returns:

    Dict with key-value pairs:

    - key: order of the variable

    - value: coefficient of that order

normalizeRational(rational, var=s, method='lowest')

  Normalizes a rational expression to:

  \[F(s) = gain\,s^{\ell} \frac{1+b_1s + ... + b_ms^m}{1+a_1s + ... + a_ns^n}\]
  Parameters:

    - Rational (sympy.Expr) – Rational function of the variable.

    - var (sympy.Symbol) – Variable of the rational function

    - method (str) –

      Normalization method:

      - ”highest”: the coefficients of the highest order of <variable> of the denominator will be noramalized to unity.

      - ”lowest”: the coefficients of the lowest order of <variable> of the denominator will be noramalized to unity.

  Returns:

    Normalized rational function of the variable.

  Return type:

    sympy.Expr

phaseMargin(LaplaceExpr)

  Calculates the phase margin assuming a loop gain definition according to the asymptotic gain model.

  This function uses scipy.newton() for determination of the the unity-gain frequency. It uses the function SLiCAPmath.findServoBandwidth() for the initial guess, and ini.disp for the relative accuracy.

  if ini.hz == True, the units will be degrees and Hz, else radians and radians per seconds.

  Parameters:

    LaplaceExpr (sympy.Expr, list) – Univariate function (sympy.Expr*) or list with univariate functions (sympy.Expr*) of the Laplace variable.

  Returns:

    Tuple with phase margin (float) and unity-gain frequency (float), or Tuple with lists with phase margins (float) and unity-gain frequencies (float).

  Return type:

    tuple

rational2float(expr)

  Converts rational numbers in expr into floats.

  Parameters:

    expr (sympy.Expression) – Sympy expression in which rational numbers need to be converterd into floats.

  Returns:

    expression in which rational numbers have been replaced with floats.

  Return type:

    sympy.Expression

rmsNoise(noiseResult, noise, fmin, fmax, source=None, CDS=False, tau=None, method='auto', points=0, wf=1)

  Calculates the RMS source-referred noise or detector-referred noise, or the contribution of a specific noise source or a collection of sources to it.

  Parameters:

    - noiseResult (SLiCAPinstruction.instruction) – Results of the execution of an instruction with data type ‘noise’.

    - noise – ‘inoise’ or ‘onoise’ for source-referred noise or detector- referred noise, respectively.

    - fmin (str, int, float, sp.Symbol) – Lower limit of the frequency range in Hz.

    - fmax (str, int, float, sp.Symbol) – Upper limit of the frequency range in Hz.

    - source (str, list) – refDes (ID) or list with IDs of noise sources of which the contribution to the RMS noise needs to be evaluated. Only IDs of current of voltage sources with a nonzero value for their ‘noise’ parameter are accepted.

    - CDS (Bool) – True if correlated double sampling is required, defaults to False If True parameter ‘tau’ must be given a nonzero finite value (can be symbolic). If method==”log” a logarithmic frequency seep will be used from the lowest frequency until the frequency of the first notch: f=1/tau. Linear sweeping will be used for all other frequency segments. The number of points per segment will be set to points. If type(points) == list, the method will be set to ‘scipy’.

    - tau (str, int, float, sp.Symbol) – CDS delay time

    - method (str) –

      Integration method, implemented methods are:

      - ”auto”: automatic selection of integration method

      - ”symbolic”: forces symbolic integration

      - ”scipy”: numeric integration using scipy.integrate.quad.

          CDS will use integration per section f=1/tau

      - ”log”: numeric integration using numpy.trapezoid with a

          logarithmic frequency sweep from f_min to f_max and the number of points (CDS: per section f=1/tau) set by points

      - ”lin”: numeric integration using numpy.trapezoid with a

          linear frequency sweep from fmin to fmax and the number of points (CDS: per section f=1/tau) set by points

      - ”list”: numeric integration using numpy.trapezoid with frequency

          points taken from points (CDS: switches method to ‘scipy’).

      Defaults to ‘auto’

    - points (int, list) – Number of frequency points for integration for method=”lin” and method=”log”, or a list with points. Defaults to 0. If type(points) == list f_min, and f_max will be redefined to the first and the last number in the list.

    - wf (str, int, float, sympy expr) – Frequency weighting function (H(s) or H(f))

  Returns:

    RMS noise over the frequency interval.

    - An expression or value if parameter stepping of the instruction is disabled.

    - A list with expressions or values if parameter stepping of the instruction is enabled.

  Return type:

    int, float, sympy.Expr

roundN(expr, numeric=False)

  Rounds all float and rational numbers in an expression to ini.disp digits, and converts integers into floats if their number of digits exceeds ini.disp

  Parameters:

    - expr (sympy.Expr) – Input expression

    - numeric (Bool) – True if numeric evaluation (pi = 3.14…) must be done

  Returns:

    modified expression

  Return type:

    sympy.Expr

routh(charPoly, eps=epsilon)

  Returns the Routh array of a polynomial of the Laplace variable (ini.laplace).

  Parameters:

    - charPoly (sympy.Expr) – Expression that can be written as a polynomial of the Laplace variable (ini.laplace).

    - eps (sympy.Symbol) – Symbolic variable used to indicate marginal stability. Use a symbol that is not present in charPoly.

  Returns:

    Routh array

  Return type:

    sympy.Matrix

  Example:

      >>> # ini.laplace = sp.Symbol('s')
      >>> s, eps = sp.symbols('s, epsilon')
      >>> charPoly = s**4+2*s**3+(3+k)*s**2+(1+k)*s+(1+k)
      >>> M = routh(charPoly, eps)
      >>> print(M.col(0)) # Number of roots in the right half plane is equal to
      >>>                 # the number of sign changes in the first column of the
      >>>                 # Routh array
      Matrix([[1], [2], [k/2 + 5/2], [(k**2 + 2*k + 1)/(k + 5)], [k + 1]])

step2PeriodicPulse(ft, t_pulse, t_period, n_periods)

  Converts a step response in a periodic pulse response. Works with symbolic and numeric time functions.

  For evaluation of numeric values, use the SLiCAP function: _makeNumData().

  Parameters:

    - ft (sympy.Expr) – Time function f(t)

    - t_pulse (int, float) – Pulse width

    - t_period (int, float) – Pulse period

    - n_periods – Number of pulses

  Typen_periods:

    int, float

  Returns:

    modified time function

  Return type:

    sympy.Expr

units2TeX(units)

  Returns units in LaTeX format, without opening and closing ‘$’.

  Parameters:

    units (str) – String representing an expression with units

  Returns:

    LaTeX code of ‘units’ without opening or closing tags.

  Return type:

    str