template <class T> T abs(const complex<T> &a) { return sqrt(a.real()*a.real() + a.imag()*a.imag()); } template <class T> T phase(const complex<T> &a) { return atan2(a.imag(), a.real()); } template <class T> complex<T> sqrt(const complex<T> &a) { const T amp = abs(a); const T pha = phase(a); complex<T> result(sqrt(amp)*cos(pha/2),sqrt(amp)*sin(pha/2)); return result; }
The script below plots the magnitude and phase of a complex impedance as a function of frequency:
#include <complex> double abs(const complex<double> &a) {return sqrt(a.real()*a.real() + a.imag()*a.imag());} complex<double> Z(double omega) { double R1 = 100; double R2 = 50; double C = 0.001; complex<double> i(0,1); // imaginary unit // R2 connected in parallel with C, and they are connected // in serial with R1 return R1 + 1/(i*omega*C + 1/R2); } // return phase in degrees double phase(double omega) { return atan2(Z(omega).imag(), Z(omega).real()) * 180.0 / 3.1415; } // return magnitude double mag(double omega) { return abs(Z(omega)); } main() { frame::current().mirror_y1(false).mirror_y2(false); frame::current().x1axis()->logscale(true); set::x1title("$\\omega$ [Hz]"); set::y1title("Magnitude [$\\Omega$]"); set::y2title("Phase [degree]"); set::x1range(1,1000); plot (_1, cfunc(mag) ).legend("Magnitude (left axis)").lw(5*LW).ac(red); mplot(_1, cfunc(phase)).legend("Phase (right axis)").lw(5*LW).ls(dashed).yaxis(axis::y2); eps::print("fff.eps"); }