Bode (magnitude and phase response of a linear transfer function)

Average rating
(1 vote)
Bode Plots of a second-order system

This gives a one-line function call that will create waves for the magnitude and phase response of a transfer function for N evenly spaced (in log) points between angular frequencies omega_1 and omega_2. One slightly non-standard feature is the use of amplitude ratios rather than dB for the magnitude plot. I think the latter units should be retired. For those who don't, converting is easy.

Because Igor is sorely lacking in support for linear systems, the format of the transfer function is a bit free-form. One day, it would be nice for Igor to have a linear system structure that would automatically handle features such as continuous or discrete dynamics, different representations (Laplace domain, pole-zero, state space, etc.), and the like. For now, this will do.

Example:

Make /o/d/n=1 pw={0.1}				// create a parameter wave; set the damping to zeta=0.1
•Bode(SecondOrder,pw,0.01,100,1000,"order2")Display order2_mag vs order2_omega                       // these are the minimal graphics commandsModifyGraph log=1                                        // the attached layout has been "prettied up" in inessential waysDisplay order2_ph vs order2_omega
•ModifyGraph log(bottom)=1

Here are the Igor functions:

//_______________________________________________________________________
 
Function Bode(tf,pars,w0,w1,N,base)     	// make waves for Bode plots (mag & phase) for transfer function
	FUNCREF myprotofunc tf			// pass function as  argument;   tf = "transfer function"
	Wave pars						// parameter wave to pass to function
	Variable w0,w1,N					// w0 = lower, w1 = upper frequencies; N = num points
	String base						// base name for output waves
	String OmegaString=base+"_omega", BodeMagString=base+"_mag", BodePhString=base+"_ph"
	Make /o/d/n=(N)$OmegaString,$BodeMagString,$BodePhString
	Wave OmegaWave=$OmegaString, BodeMagWave=$BodeMagString, BodePhWave=$BodePhString
	OmegaWave = w0*(w1/w0)^(p/(N-1))	        // even spacing on log
	Variable /c i=cmplx(0,1)			// define i=sqrt(-1)
	Make /free/c/d/n=(N) ss = i*OmegaWave	      // temporary wave for s = iw
	BodeMagWave = cabs(tf(pw,ss))			// magnitude of frequency response
	BodePhWave = atan2(imag(tf(pw,ss)),real(tf(pw,ss)))*180/pi		// output phase in degrees
	Unwrap 360, BodePhWave					// prevent any 360 degree phase jumps
End	
 
Function/c myprotofunc(pars,s)					// format of prototype function (transfer function)
	Wave pars; Variable /c s				// pars = parameters; s = Laplace domain
End
 
//_______________________________________________________________________
 
Function/c SecondOrder(pars,s)                                   // substitute your own transfer function here
	Wave pars; Variable/c s
	Variable zeta=pars[0]					// zeta = dimensionless damping coefficient
	Return 1/(1+2*zeta*s+s^2)				// standard scaled 2nd-order response function
End
 
//_________________________________________________

Back to top