There is the complex<>
template in C++ standard library, and it has an overloaded << operator so that it outputs complex numbers in the (real_part, im_part) format. I need to change the behavior of that operator for complex numbers so that the output format is changed to something completely different. Specifically, I need the output to be in the form real_part\tim_part
. How do I do that?
The standard form of writing a complex number is z = a + ib. The standard form of the complex number has two parts, the real part, and the imaginary part. In the complex number z = a + ib, a is the real part and ib is the imaginary part.
It should be relatively easy to see that, if a complex number z has magnitude r and argument θ, then: z=r(cosθ+isinθ) This is called the polar form of a complex number. Thus, if you want to convert from polar form to rectangular form, remember that Re(z)=rcosθ and Im(z)=rsinθ.
An complex number is represented by “ x + yi “. Python converts the real numbers x and y into complex using the function complex(x,y). The real part can be accessed using the function real() and imaginary part can be represented by imag().
Python adopted the convention used by electrical engineers. In that field, i is used to represent current and use j as the square root of -1.
There's no direct way to replace operator <<
, but you do have a few options. First, you could just write your own function to print complex numbers:
template <typename T> void PrintComplex(const complex<T>& c) {
/* ... */
}
If you want to still use the nice stream syntax, then one trick you could do would be to make a wrapper class that wraps a complex
and then defines its own operator <<
that prints it out in a different way. For example:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
complex<T> c;
};
Once you have this, you could write something like
cout << ComplexPrinter<double>(myComplex) << endl;
You can make this even cleaner by writing a function like this one to wrap the object for you:
template <typename T>
ComplexPrinter<T> wrap(const complex<T>& c) {
return ComplexPrinter<T>(c);
}
This then lets you write
cout << wrap(myComplex) << endl;
Which isn't perfect, but is pretty good.
One thing to note about the above wrapper is that it has an implicit conversion constructor set up to let you convert complex<T>
s to ComplexPrinter<T>
s. This means that if you have a vector< complex<T> >
, you can print it out using your custom code by calling
vector< complex<double> > v = /* ... */
copy (v.begin(), v.end(), ostream_iterator< ComplexPrinter<double> >(cout, " "));
On output, the implicit conversion constructor will transform your complex<double>
s into the wrappers, and your custom code will do the printing for you.
If you want to be very adventurous and cast caution to the wind, you could even write the class so that it just stores a reference to the original complex
, as shown here:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
const complex<T>& c;
};
This completely eliminates any copying and just makes the wrapper a thin veneer around a real complex
. (No pun intended). You'd have to be very careful if you did this not to pass these objects around across scope boundaries where the original objects go out of scope, but if it's what you want it might work out just great.
Hope this helps!
template<class T>
struct my_complex_format_type {
std::complex<T> const &x;
my_complex_format_type(std::complex<T> const &x) : x (x) {}
friend std::ostream& operator<<(std::ostream &out,
my_complex_format_type const &value)
{
out << "format value.x however you like";
return out;
}
};
template<class T>
my_complex_format_type<T> my_complex_format(std::complex<T> const &x) {
return x;
}
void example() {
std::cout << my_complex_format(some_complex);
}
For any specific instantiation of complex<T>
, Use a strong typedef (boost has a version) and cast to that type during << calls. Override << for that type.
If you need to override << for any variation of complex<T>
then life will be harder.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With