Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the complex number output format

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?

like image 928
grzkv Avatar asked Feb 14 '11 06:02

grzkv


People also ask

What is the format of a complex number?

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.

How do you convert complex numbers to rectangular form?

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θ.

How do you print complex numbers in Python?

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().

Why does Python use j instead of i for complex numbers?

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.


3 Answers

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!

like image 127
templatetypedef Avatar answered Oct 04 '22 03:10

templatetypedef


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);
}
like image 20
Fred Nurk Avatar answered Oct 04 '22 03:10

Fred Nurk


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.

like image 34
Edward Strange Avatar answered Oct 04 '22 03:10

Edward Strange