K iddlmZmZddlmZmZddlmZddlm Z ddl m Z ddl m Z mZddlmZddlmZdd lmZdd lmZdd lmZmZdd lmZdd lmZddlmZgdZ e dddgie!fZ"e"r e"jFZ$dZ%dZ&dZ' d(dZ( d)dZ) d*dZ* d)dZ+ d*dZ, d+dZ- d,dZ.d-dZ/ d.dZ0d/d Z1 d0d!Z2 d1d"Z3d#Z4d$Z5 d2d%Z6d2d&Z7y')3)Ipi)explog)apart)Dummy) import_module)argAbs)_fast_inverse_laplace)SISOLinearTimeInvariant)LineOver1DRangeSeries)plot_parametric)ZZQQ)Poly)latex)deg)pole_zero_numerical_datapole_zero_plotstep_response_numerical_datastep_response_plotimpulse_response_numerical_dataimpulse_response_plotramp_response_numerical_dataramp_response_plotbode_magnitude_numerical_databode_phase_numerical_databode_magnitude_plotbode_phase_plot bode_plotnyquist_plot_expr nyquist_plotnichols_plot_expr nichols_plot matplotlibfromlistpyplot) import_kwargscatchct|ts td|j}t |j }|dkDr t d|jtr tdy)zYFunction to check whether the dynamical system passed for plots is compatible or not.z.Only SISO LTI systems are currently supported.zExtra degree of freedom found. Make sure that there are no free symbols in the dynamical system other than the variable of Laplace transform.z#Time delay terms are not supported.N) isinstancer NotImplementedErrorto_exprlen free_symbols ValueErrorhasr)systemsyslen_free_symbolss i/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/physics/control/control_plots.py _check_systemr8"sr f5 6!"RSS .. C3++,!78 8 wws|""GHHcd}|jttfvr||jS||j S)z*Function to get the roots of a polynomial.cl|Dcgc]$}|jr t|n t|&c}Scc}w)N)is_realfloatcomplex)lis r7_evalz_poly_roots.._eval5s)?@A!AIIa71:5AAAs)1)domainrr all_rootsnroots)polyrAs r7 _poly_rootsrF3s=B {{r2hT^^%&&  r9ct||j}t|j|j}t|j |j}t |t |fS)a Returns the numerical data of poles and zeros of the system. It is internally used by ``pole_zero_plot`` to get the data for plotting poles and zeros. Users can use this data to further analyse the dynamics of the system or plot using a different backend/plotting-module. Parameters ========== system : SISOLinearTimeInvariant The system for which the pole-zero data is to be computed. Returns ======= tuple : (zeros, poles) zeros = Zeros of the system as a list of Python float/complex. poles = Poles of the system as a list of Python float/complex. Raises ====== NotImplementedError When a SISO LTI system is not passed. When time delay terms are present in the system. ValueError When more than one free symbol is present in the system. The only variable in the transfer function should be the variable of the Laplace transform. Examples ======== >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import pole_zero_numerical_data >>> tf1 = TransferFunction(s**2 + 1, s**4 + 4*s**3 + 6*s**2 + 5*s + 2, s) >>> pole_zero_numerical_data(tf1) ([-1j, 1j], [-2.0, -1.0, (-0.5-0.8660254037844386j), (-0.5+0.8660254037844386j)]) See Also ======== pole_zero_plot )r8doitrnumvardenrF)r4num_polyden_polys r7rr>sUd& [[]FFJJ +HFJJ +H x +h"7 77r9c t|\} } | D cgc]} | j} } | D cgc]} | j} } | D cgc]} | j}} | D cgc]} | j}} tj ||dd||tj | | d||tj dtj dtjdt|d d |rtj|r.tjd d tjd d |rtjytScc} wcc} wcc} wcc} w)a Returns the Pole-Zero plot (also known as PZ Plot or PZ Map) of a system. A Pole-Zero plot is a graphical representation of a system's poles and zeros. It is plotted on a complex plane, with circular markers representing the system's zeros and 'x' shaped markers representing the system's poles. Parameters ========== system : SISOLinearTimeInvariant type systems The system for which the pole-zero plot is to be computed. pole_color : str, tuple, optional The color of the pole points on the plot. Default color is blue. The color can be provided as a matplotlib color string, or a 3-tuple of floats each in the 0-1 range. pole_markersize : Number, optional The size of the markers used to mark the poles in the plot. Default pole markersize is 10. zero_color : str, tuple, optional The color of the zero points on the plot. Default color is orange. The color can be provided as a matplotlib color string, or a 3-tuple of floats each in the 0-1 range. zero_markersize : Number, optional The size of the markers used to mark the zeros in the plot. Default zero markersize is 7. grid : boolean, optional If ``True``, the plot will have a grid. Defaults to True. show_axes : boolean, optional If ``True``, the coordinate axes will be shown. Defaults to False. show : boolean, optional If ``True``, the plot will be displayed otherwise the equivalent matplotlib ``plot`` object will be returned. Defaults to True. Examples ======== .. plot:: :context: close-figs :format: doctest :include-source: True >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import pole_zero_plot >>> tf1 = TransferFunction(s**2 + 1, s**4 + 4*s**3 + 6*s**2 + 5*s + 2, s) >>> pole_zero_plot(tf1) # doctest: +SKIP See Also ======== pole_zero_numerical_data References ========== .. [1] https://en.wikipedia.org/wiki/Pole%E2%80%93zero_plot xnone)mfc markersizecoloro)rRrS Real AxisImaginary AxiszPoles and Zeros of $$padrblackrSN) rrealimagpltplotxlabelylabeltitlergridaxhlineaxvlineshow)r4 pole_colorpole_markersize zero_colorzero_markersizerd show_axesrgkwargszerospolesr@ zero_real zero_imag pole_real pole_imags r7rrys1~,F3LE5!&'A'I'!&'A'I'!&'A'I'!&'A'I'HHY 3F"* 6HHY 3? JJ{JJ II$U6]O152I>    AW % AW %    J/('''sEEE#E(c @|dkr tdt|td}|j|jz }t ||jd}t ||j|j|}t||||ffi|jS)a Returns the numerical values of the points in the step response plot of a SISO continuous-time system. By default, adaptive sampling is used. If the user wants to instead get an uniformly sampled response, then ``adaptive`` kwarg should be passed ``False`` and ``n`` must be passed as additional kwargs. Refer to the parameters of class :class:`sympy.plotting.series.LineOver1DRangeSeries` for more details. Parameters ========== system : SISOLinearTimeInvariant The system for which the unit step response data is to be computed. prec : int, optional The decimal point precision for the point coordinate values. Defaults to 8. lower_limit : Number, optional The lower limit of the plot range. Defaults to 0. upper_limit : Number, optional The upper limit of the plot range. Defaults to 10. kwargs : Additional keyword arguments are passed to the underlying :class:`sympy.plotting.series.LineOver1DRangeSeries` class. Returns ======= tuple : (x, y) x = Time-axis values of the points in the step response. NumPy array. y = Amplitude-axis values of the points in the step response. NumPy array. Raises ====== NotImplementedError When a SISO LTI system is not passed. When time delay terms are present in the system. ValueError When more than one free symbol is present in the system. The only variable in the transfer function should be the variable of the Laplace transform. When ``lower_limit`` parameter is less than 0. Examples ======== >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import step_response_numerical_data >>> tf1 = TransferFunction(s, s**2 + 5*s + 8, s) >>> step_response_numerical_data(tf1) # doctest: +SKIP ([0.0, 0.025413462339411542, 0.0484508722725343, ... , 9.670250533855183, 9.844291913708725, 10.0], [0.0, 0.023844582399907256, 0.042894276802320226, ..., 6.828770759094287e-12, 6.456457160755703e-12]) See Also ======== step_response_plot r:Lower limit of time must be greater than or equal to zero.rOTfull r2r8rr/rJrr evalfr get_pointsr4prec lower_limit upper_limitrm_xexpr_ys r7rrsDQ%& && sB >> VZZ (D vzz -D tVZZ 4 : :4 @B b+{%C   *,r9c t|f|||d|\} } tj| | |tjdtj dtj dt |dd|rtj|r.tjd d tjd d |rtjy tS) a Returns the unit step response of a continuous-time system. It is the response of the system when the input signal is a step function. Parameters ========== system : SISOLinearTimeInvariant type The LTI SISO system for which the Step Response is to be computed. color : str, tuple, optional The color of the line. Default is Blue. show : boolean, optional If ``True``, the plot will be displayed otherwise the equivalent matplotlib ``plot`` object will be returned. Defaults to True. lower_limit : Number, optional The lower limit of the plot range. Defaults to 0. upper_limit : Number, optional The upper limit of the plot range. Defaults to 10. prec : int, optional The decimal point precision for the point coordinate values. Defaults to 8. show_axes : boolean, optional If ``True``, the coordinate axes will be shown. Defaults to False. grid : boolean, optional If ``True``, the plot will have a grid. Defaults to True. Examples ======== .. plot:: :context: close-figs :format: doctest :include-source: True >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import step_response_plot >>> tf1 = TransferFunction(8*s**2 + 18*s + 32, s**3 + 6*s**2 + 14*s + 24, s) >>> step_response_plot(tf1) # doctest: +SKIP See Also ======== impulse_response_plot, ramp_response_plot References ========== .. [1] https://www.mathworks.com/help/control/ref/lti.step.html r|r}r~r\Time (s) AmplitudezUnit Step Response of $rWrXrYrr[N) rr_r`rarbrcrrdrerfrg r4rSr|r}r~rlrdrgrmrOys r7rr"sl ( DT[ D>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import impulse_response_numerical_data >>> tf1 = TransferFunction(s, s**2 + 5*s + 8, s) >>> impulse_response_numerical_data(tf1) # doctest: +SKIP ([0.0, 0.06616480200395854,... , 9.854500743565858, 10.0], [0.9999999799999999, 0.7042848373025861,...,7.170748906965121e-13, -5.1901263495547205e-12]) See Also ======== impulse_response_plot rrurOTrv) r2r8rr/rrJr ryrrzr{s r7rrksDQ%& && sB >> D vzz -D tVZZ 4 : :4 @B b+{%C   *,r9c t|f|||d|\} } tj| | |tjdtj dtj dt |dd|rtj|r.tjd d tjd d |rtjy tS) a Returns the unit impulse response (Input is the Dirac-Delta Function) of a continuous-time system. Parameters ========== system : SISOLinearTimeInvariant type The LTI SISO system for which the Impulse Response is to be computed. color : str, tuple, optional The color of the line. Default is Blue. show : boolean, optional If ``True``, the plot will be displayed otherwise the equivalent matplotlib ``plot`` object will be returned. Defaults to True. lower_limit : Number, optional The lower limit of the plot range. Defaults to 0. upper_limit : Number, optional The upper limit of the plot range. Defaults to 10. prec : int, optional The decimal point precision for the point coordinate values. Defaults to 8. show_axes : boolean, optional If ``True``, the coordinate axes will be shown. Defaults to False. grid : boolean, optional If ``True``, the plot will have a grid. Defaults to True. Examples ======== .. plot:: :context: close-figs :format: doctest :include-source: True >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import impulse_response_plot >>> tf1 = TransferFunction(8*s**2 + 18*s + 32, s**3 + 6*s**2 + 14*s + 24, s) >>> impulse_response_plot(tf1) # doctest: +SKIP See Also ======== step_response_plot, ramp_response_plot References ========== .. [1] https://www.mathworks.com/help/control/ref/dynamicsystem.impulse.html rr\rrzImpulse Response of $rWrXrYrr[N) rr_r`rarbrcrrdrerfrgrs r7rrsl +6 D[ D>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import ramp_response_numerical_data >>> tf1 = TransferFunction(s, s**2 + 5*s + 8, s) >>> ramp_response_numerical_data(tf1) # doctest: +SKIP (([0.0, 0.12166980856813935,..., 9.861246379582118, 10.0], [1.4504508011325967e-09, 0.006046440489058766,..., 0.12499999999568202, 0.12499999999661349])) See Also ======== ramp_response_plot rz,Slope must be greater than or equal to zero.rurOTrvrx) r4sloper|r}r~rmrrrs r7rrsL qy Q%& && sB &.." "fjj1_ 5D vzz -D tVZZ 4 : :4 @B b+{%C   *,r9c  t|f||||d| \} } tj| | |tjdtj dtj dt |d|dd |rtj|r.tjd d tjd d |rtjy tS) a> Returns the ramp response of a continuous-time system. Ramp function is defined as the straight line passing through origin ($f(x) = mx$). The slope of the ramp function can be varied by the user and the default value is 1. Parameters ========== system : SISOLinearTimeInvariant type The LTI SISO system for which the Ramp Response is to be computed. slope : Number, optional The slope of the input ramp function. Defaults to 1. color : str, tuple, optional The color of the line. Default is Blue. show : boolean, optional If ``True``, the plot will be displayed otherwise the equivalent matplotlib ``plot`` object will be returned. Defaults to True. lower_limit : Number, optional The lower limit of the plot range. Defaults to 0. upper_limit : Number, optional The upper limit of the plot range. Defaults to 10. prec : int, optional The decimal point precision for the point coordinate values. Defaults to 8. show_axes : boolean, optional If ``True``, the coordinate axes will be shown. Defaults to False. grid : boolean, optional If ``True``, the plot will have a grid. Defaults to True. Examples ======== .. plot:: :context: close-figs :format: doctest :include-source: True >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import ramp_response_plot >>> tf1 = TransferFunction(s, (s+4)*(s+8), s) >>> ramp_response_plot(tf1, upper_limit=2) # doctest: +SKIP See Also ======== step_response_plot, impulse_response_plot References ========== .. [1] https://en.wikipedia.org/wiki/Ramp_function )rr|r}r~r\rrzRamp Response of $z $ [Slope = ]rXrYrr[N) rr_r`rarbrcrrdrerfrg) r4rrSr|r}r~rlrdrgrmrOrs r7rrWsx ( De$[ D>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import bode_magnitude_numerical_data >>> tf1 = TransferFunction(s**2 + 1, s**4 + 4*s**3 + 6*s**2 + 5*s + 2, s) >>> bode_magnitude_numerical_data(tf1) # doctest: +SKIP ([1e-05, 1.5148378120533502e-05,..., 68437.36188804005, 100000.0], [-6.020599914256786, -6.0205999155219505,..., -193.4117304087953, -200.00000000260573]) See Also ======== bode_magnitude_plot, bode_phase_numerical_data rad/secHz5Only "rad/sec" and "Hz" are accepted frequency units.wTr]rrrX xscaler) r8r/r2rrrsubsrJrr rrz) r4 initial_exp final_exp freq_unitrmr freq_units_wreplw_exprmagrOrs r7rrsv& >> D"J "PQQ s BDtAvbyt YY D) *F SVb ! !C  R_b)m, F5: F>D FFPjl Aq a4Kr9c t||||\} } tj| | fd|i|tjdtj d|ztj dtj dt|dd |rtjd |r.tjd d tjd d |rtjytS)zu Returns the Bode magnitude plot of a continuous-time system. See ``bode_plot`` for all the parameters. )rrrrSrFrequency (%s) [Log Scale]zMagnitude (dB)zBode Plot (Magnitude) of $rWrXrYTrr[r\N) rr_r`rrarbrcrrdrerfrg) r4rrrSrlrdrgrrmrOrs r7rrs )[y 2DAqHHQ))&)JJuJJ+i78JJ II*5=/;ID   AW % AW %    Jr9c t||j}d}d} ||vr td|| vr tdtdd} |dk(rt| zd zt z} n t| z} |j |j| i} |d k(rt| d zt z } n t| } t| | d |zd |zffd di|j\}}d}|r|dk(rt }n|d k(rd }|rPd |z}tdt|D]3}||||dz z }||kDr |||z ||<"|| ks)|||z||<5||fS)a Returns the numerical data of the Bode phase plot of the system. It is internally used by ``bode_phase_plot`` to get the data for plotting Bode phase plot. Users can use this data to further analyse the dynamics of the system or plot using a different backend/plotting-module. Parameters ========== system : SISOLinearTimeInvariant The system for which the Bode phase plot data is to be computed. initial_exp : Number, optional The initial exponent of 10 of the semilog plot. Defaults to -5. final_exp : Number, optional The final exponent of 10 of the semilog plot. Defaults to 5. freq_unit : string, optional User can choose between ``'rad/sec'`` (radians/second) and '``'Hz'`` (Hertz) as frequency units. phase_unit : string, optional User can choose between ``'rad'`` (radians) and ``'deg'`` (degree) as phase units. phase_unwrap : bool, optional Set to ``True`` by default. Returns ======= tuple : (x, y) x = x-axis values of the Bode phase plot. y = y-axis values of the Bode phase plot. Raises ====== NotImplementedError When a SISO LTI system is not passed. When time delay terms are present in the system. ValueError When more than one free symbol is present in the system. The only variable in the transfer function should be the variable of the Laplace transform. When incorrect frequency or phase units are given as input. Examples ======== >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import bode_phase_numerical_data >>> tf1 = TransferFunction(s**2 + 1, s**4 + 4*s**3 + 6*s**2 + 5*s + 2, s) >>> bode_phase_numerical_data(tf1) # doctest: +SKIP ([1e-05, 1.4472354033813751e-05, 2.035581932165858e-05,..., 47577.3248186011, 67884.09326036123, 100000.0], [-2.5000000000291665e-05, -3.6180885085e-05, -5.08895483066e-05,...,-3.1415085799262523, -3.14155265358979]) See Also ======== bode_magnitude_plot, bode_phase_numerical_data r)radrrz.Only "rad" and "deg" are accepted phase units.rTrrrrrrrNrr,) r8r/r2rrrrrJr rrzranger0)r4rrr phase_unit phase_unwraprmrr phase_unitsrrrphaserOrhalfunitr@diffs r7rrs~& >> D"J K "PQQ$IJJ s BDtAvbyt YY D) *FUF C"F   R_b)m, F5: F>D FFPjl Aq D  D 5 D vq#a&! %AQ4!AE(?Dd{!t !!t !  % a4Kr9c  t|||||| \} } tj| | fd|i| tjdtj d|ztj d|ztj dt|dd |rtjd |r.tjd d tjd d |rtjytS)zq Returns the Bode phase plot of a continuous-time system. See ``bode_plot`` for all the parameters. )rrrrrrSrrz Phase (%s)zBode Plot (Phase) of $rWrXrYTrr[r\N) rr_r`rrarbrcrrdrerfrg) r4rrrSrlrdrgrrrrmrOrs r7r r |s %VyZVb dDAqHHQ))&)JJuJJ+i78JJ|j()II&uV}oQ7RI@   AW % AW %    Jr9c `tjdt|f||d|||d| } | jdt |dd| j dtjd t |f||d|||||d | jd|rtjytS) a Returns the Bode phase and magnitude plots of a continuous-time system. Parameters ========== system : SISOLinearTimeInvariant type The LTI SISO system for which the Bode Plot is to be computed. initial_exp : Number, optional The initial exponent of 10 of the semilog plot. Defaults to -5. final_exp : Number, optional The final exponent of 10 of the semilog plot. Defaults to 5. show : boolean, optional If ``True``, the plot will be displayed otherwise the equivalent matplotlib ``plot`` object will be returned. Defaults to True. prec : int, optional The decimal point precision for the point coordinate values. Defaults to 8. grid : boolean, optional If ``True``, the plot will have a grid. Defaults to True. show_axes : boolean, optional If ``True``, the coordinate axes will be shown. Defaults to False. freq_unit : string, optional User can choose between ``'rad/sec'`` (radians/second) and ``'Hz'`` (Hertz) as frequency units. phase_unit : string, optional User can choose between ``'rad'`` (radians) and ``'deg'`` (degree) as phase units. Examples ======== .. plot:: :context: close-figs :format: doctest :include-source: True >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import bode_plot >>> tf1 = TransferFunction(1*s**2 + 0.1*s + 7.5, 1*s**4 + 0.12*s**3 + 9*s**2, s) >>> bode_plot(tf1, initial_exp=0.2, final_exp=0.7) # doctest: +SKIP See Also ======== bode_magnitude_plot, bode_phase_plot F)rrrgrdrlrzBode Plot of $rWrXrYN)rrrgrdrlrrr)r_subplotrrcrrar rg) r4rrrdrlrgrrrrmrs r7r!r!sdKK f '+  '% 'CIIuV}oQ/RI8JJtKKFE y iT^myE~DEFKFKLPFQ    Jr9c|j}tdd}t|z}|j}|j ||i}|j }|d}|d}|||fS)z0Function to get the expression for Nyquist plot.rTrrr,)rJrrr/r as_real_imag)r4srrrr real_expr imag_exprs r7r"r"sk A cA q5D >> D YY4y !F  "Fq Iq I i ""r9c|j}tdd}|j}|j|t|z}t |}dt |dz}t|}t|}|||fS)z0Function to get the expression for Nichols plot.rTrrXr) rJrr/rrr rr r) r4rrsys_exprH_jwmag_expr mag_dB_expr phase_exprphase_deg_exprs r7r$r$sp A cA~~H ==AaC D4yHS2&&KTJ_N  ))r9c t|t|\}}}|||fg} t||f|| fg| d|ddt|dddd|d} |r| j y | S) a Generates the Nyquist plot for a continuous-time system. Parameters ========== system : SISOLinearTimeInvariant The LTI SISO system for which the Nyquist plot is to be generated. initial_omega : float, optional The starting frequency value. Defaults to 0.01. final_omega : float, optional The ending frequency value. Defaults to 100. show : bool, optional If True, the plot is displayed. Default is True. color : str, optional The color of the Nyquist plot. Default is 'b' (blue). grid : bool, optional If True, grid lines are displayed. Default is False. **kwargs Additional keyword arguments for customization. Examples ======== .. plot:: :context: close-figs :format: doctest :include-source: True >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import nyquist_plot >>> tf1 = TransferFunction(2*s**2 + 5*s + 1, s**2 + 2*s + 3, s) >>> nyquist_plot(tf1) # doctest: +SKIP See Also ======== nichols_plot, bode_plot FTzNyquist Plot of $rWrUrV)rg line_coloradaptivercrarbsizermN)r8r"rrrg) r4 initial_omega final_omegargrSrmrrrw_valuesps r7r#r#sV&/7Iy!M;/0H I YJ   !%-2  A   Hr9c t|t|\}}}|||fg} t||fg| d|dt|dddd|d} |r| j y| S) a Generates the Nichols plot for a LTI system. Parameters ========== system : SISOLinearTimeInvariant The LTI SISO system for which the Nyquist plot is to be generated. initial_omega : float, optional The starting frequency value. Defaults to 0.01. final_omega : float, optional The ending frequency value. Defaults to 100. show : bool, optional If True, the plot is displayed. Default is True. color : str, optional The color of the Nyquist plot. Default is 'b' (blue). grid : bool, optional If True, grid lines are displayed. Default is False. **kwargs Additional keyword arguments for customization. Examples ======== .. plot:: :context: close-figs :format: doctest :include-source: True >>> from sympy.abc import s >>> from sympy.physics.control.lti import TransferFunction >>> from sympy.physics.control.control_plots import nichols_plot >>> tf1 = TransferFunction(1.5, s**2+14*s+40.02, s) >>> nichols_plot(tf1) # doctest: +SKIP See Also ======== nyquist_plot, bode_plot FzNichols Plot of $rWz Phase [deg]zMagnitude [dB]r)rgrrcrarbrrmN)r8r$rrrg) r4rrrgrSrmmagnitude_dB_exprrrrrs r7r%r%5sT&+rs>$=&#($9=7/&&&& Z($<o    CI" 88v?AAE Xv>?K\?@59FRABK\BC59FR89!RjHI59L^M`;<@I:fR78jn812_c@F # *DH= @: r9