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");
}