C Complex Numbers in C++

How to work with complex numbers in C?

This code will help you, and it's fairly self-explanatory:

#include <stdio.h>      /* Standard Library of Input and Output */
#include <complex.h> /* Standard Library of Complex Numbers */

int main() {

double complex z1 = 1.0 + 3.0 * I;
double complex z2 = 1.0 - 4.0 * I;

printf("Working with complex numbers:\n\v");

printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n", creal(z1), cimag(z1), creal(z2), cimag(z2));

double complex sum = z1 + z2;
printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum));

double complex difference = z1 - z2;
printf("The difference: Z1 - Z2 = %.2f %+.2fi\n", creal(difference), cimag(difference));

double complex product = z1 * z2;
printf("The product: Z1 x Z2 = %.2f %+.2fi\n", creal(product), cimag(product));

double complex quotient = z1 / z2;
printf("The quotient: Z1 / Z2 = %.2f %+.2fi\n", creal(quotient), cimag(quotient));

double complex conjugate = conj(z1);
printf("The conjugate of Z1 = %.2f %+.2fi\n", creal(conjugate), cimag(conjugate));

return 0;
}

 
with:

creal(z1): get the real part (for float crealf(z1), for long double creall(z1))

cimag(z1): get the imaginary part (for float cimagf(z1), for long double cimagl(z1))

Another important point to remember when working with complex numbers is that functions like cos(), exp() and sqrt() must be replaced with their complex forms, e.g. ccos(), cexp(), csqrt().

C complex number and printf

printf("%f + i%f\n", creal(result), cimag(result));

I don't believe there's a specific format specifier for the C99 complex type.

C Complex Numbers in C++?

Use the C keyword for complex: _Complex. C++ uses complex as a (template) class.
I'm not sure where creal is or I would uncomment that.

#include <complex.h>
#include <cstdio>

int main(int argc, char * argv[]) {
double _Complex a = 3.0 + 0.0I; // DECLARATION WORKS NOW - NOTE ASSIGNMENT MUST HAVE IMAG PART
//printf("%lf\n", creal(a));
return 0;
}

This works in gcc (I compiled with g++). I got a warning about deprecated .h headers.

Here is a link to an email trail showing nonstandard compatibility with C++ and C with complex numbers. C++11 requires layout compatibility of C++ complexes with C _Complexes.

I'm currently investigating creal, etc. in C++. I'm not finding anything in the standard. Since there seems to be some effort to provide some source compatibility between C++ and C then creal, cpow, etc. might make a nice addition to TR2 the library proposals.

How to read complex number using complex.h in C?

complex.h does not declare or define:

  • any facilities for input or output,
  • any facilities for conversion between strings and complex numbers, or
  • any means of accessing an lvalue for the parts of a complex number, which would be necessary to store values in those parts via a scanf or similar function.

Thus, it is unclear what your teacher meant by directing you to use complex.h to read complex numbers. When writing, we can use creal and cimag to obtain the values of the parts, and those are declared in complex.h.

There are means to access lvalues for the parts of a complex number. C 6.2.5 13 says “Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.” Although this statement lacks some formal niceties, we can tell, by analogy to other wording in the standard, that it intends to tell us that we can convert a pointer to complex double to a pointer to double [2] and use that to access the parts. Thus, we can do:

#include <complex.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
complex double x;
double *y = * (double (*)[2]) &x;
if (2 != scanf("(%lg,%lg)", &y[0], &y[1]))
{
fputs("Error, scanf failed.\n", stderr);
exit(EXIT_FAILURE);
}
printf("Read %g + %g i.\n", creal(x), cimag(x));
}

Complex number in C

Section 7.3 in the C99 Standard (or C11 Standard) deals with complex numbers.

Example code

#include <complex.h>
#include <stdio.h>

int main(void) {
double A, b, c, D, e, f;
complex double x;
const complex double i = csqrt(-1);

A = 1;
b = 2;
c = 3;
D = 4;
e = 5;
f = 6;
x = A * cexp(i * (b + c)) + D * cexp(i * (e + f));
printf("value is %f + %fi\n", creal(x), cimag(x));
}

You can see the code running at ideone: http://ideone.com/d7xD7

The output is

value is 0.301365 + -4.958885i

How to efficiently work with complex numbers in C language?

Use the standard version of it. It is nowadays integrated into compilers and is the best you can get.

How is double complex actually passed into function and returned from function?

They are accessible by value as the specification of your function indicates, and as would be the case for any other function parameters, unless they have an array type.

Complex numbers are guaranteed to have the same representation (= memory layout) as a vector of two reals, but they are proper types:

Each complex type has the same representation and alignment requirements as an array
type containing exactly two elements of the corresponding real type; the first element is
equal to the real part, and the second element to the imaginary part, of the complex
number.

Although their byte pattern is the same as a two element vector of floating point values, they are considered as arithmetic types like any other number.

How to use C complex numbers in 'language=c++' mode?

Your problem has nothing to do with the fact, that one module is compiled as a C-extension and the other as a C++-extension - one can easily reproduce the issue in a C++-extension alone:

%%cython -+ 
cdef extern from "complex.h":
double cabs(double complex zz) nogil

def cpp_complex_fun(double complex xx):
return cabs(xx)

results in your error-message:

error: cannot convert __pyx_t_double_complex {aka
std::complex<double>}
to __complex__ double for argument 1 to
double cabs(__complex__ double)

The problem is that the complex numbers are ... well, complex. Cython's strategy (can be looked up here and here) to handle complex numbers is to use an available implementation from C/CPP and if none is found a hand-written fallback is used:

#if !defined(CYTHON_CCOMPLEX)
#if defined(__cplusplus)
#define CYTHON_CCOMPLEX 1
#elif defined(_Complex_I)
#define CYTHON_CCOMPLEX 1
#else
#define CYTHON_CCOMPLEX 0
#endif
#endif
....
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
typedef ::std::complex< double > __pyx_t_double_complex;
#else
typedef double _Complex __pyx_t_double_complex;
#endif
#else
typedef struct { double real, imag; } __pyx_t_double_complex;
#endif

In case of a C++-extension, Cython's double complex is translated to std::complex<double> and thus cannot be called with cabs( double complex z ) because std::complex<double> isn't double complex.

So actually, it is your "fault": you lied to Cython and told him, that cabs has the signature double cabs(std::complex<double> z), but it was not enough to fool the c++-compiler.

That means, in c++-module std::abs(std::complex<double>) could be used, or just Cython's/Python's abs, which is automatically translated to the right function (this is however not possible for all standard-function).


In case of the C-extension, because you have included complex.h as an so called "early include" with cdef extern from "complex.h", thus for the above defines _Complex_I becomes defined and Cython's complex becomes an alias for double complex and thus cabs can be used.


Probably the right thing for Cython would be to always use the fallback per default and that the user should be able to choose the desired implementation (double complex or std::complex<double>) explicitly.

Computing e^(-j) in C

Note that exponent of complex number equals:

e^(ix) = cos(x)+i*sin(x)

Then:

e^(-i) = cos(-1)+i*sin(-1)


Related Topics



Leave a reply



Submit