473,395 Members | 1,692 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Complex question

hi

I am trying to use the complex data type.

Consider this code, taken from the cclib library:

struct complex csqrt(Cpx z)
{ double r;
r=sqrt(z.re*z.re+z.im*z.im);
r=sqrt(ldexp(r+fabs(z.re),-1));
if(r==0.) z.re=z.im=0.;
else{
if(z.re>=0.){ z.re=r; z.im=ldexp(z.im/r,-1);}
else{ z.re=ldexp(fabs(z.im)/r,-1);
if(z.im>=0.) z.im=r; else z.im= -r;
}
}
return z;
}

Now, this works in lcc-win easily because lcc-win
allows access to the real and imaginary parts of the complex
data type easily, using
z.re (real part)
and
ze.im

for the imaginary part.

I do not see how can be this written in standard C.
Has anyone an idea?

Thanks
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jan 24 '08 #1
11 2369
On Jan 24, 2:03*pm, jacob navia <ja...@nospam.comwrote:
hi

I am trying to use the complex data type.

Consider this code, taken from the cclib library:

struct complex csqrt(Cpx z)
{ double r;
* *r=sqrt(z.re*z.re+z.im*z.im);
* *r=sqrt(ldexp(r+fabs(z.re),-1));
* *if(r==0.) z.re=z.im=0.;
* *else{
* * *if(z.re>=0.){ z.re=r; z.im=ldexp(z.im/r,-1);}
* * *else{ z.re=ldexp(fabs(z.im)/r,-1);
* * * *if(z.im>=0.) z.im=r; else z.im= -r;
* * * }
* * }
* *return z;

}

Now, this works in lcc-win easily because lcc-win
allows access to the real and imaginary parts of the complex
data type easily, using
z.re (real part)
and
ze.im

for the imaginary part.

I do not see how can be this written in standard C.
Has anyone an idea?
To get the imaginary part:

#include <complex.h>
double cimag(double complex z);
float cimagf(float complex z);
long double cimagl(long double complex z);

But then again, to get the square root, you would just call the
function:

#include <complex.h>
double complex csqrt(double complex z);
float complex csqrtf(float complex z);
long double complex csqrtl(long double complex z);

So I guess you do not have the header complex.h?
In such a case, maybe this is helpful:
http://www.moshier.net/#Complex_variables
Jan 24 '08 #2
On Jan 24, 2:03*pm, jacob navia <ja...@nospam.comwrote:
hi

I am trying to use the complex data type.

Consider this code, taken from the cclib library:

struct complex csqrt(Cpx z)
{ double r;
* *r=sqrt(z.re*z.re+z.im*z.im);
* *r=sqrt(ldexp(r+fabs(z.re),-1));
* *if(r==0.) z.re=z.im=0.;
* *else{
* * *if(z.re>=0.){ z.re=r; z.im=ldexp(z.im/r,-1);}
* * *else{ z.re=ldexp(fabs(z.im)/r,-1);
* * * *if(z.im>=0.) z.im=r; else z.im= -r;
* * * }
* * }
* *return z;

}

Now, this works in lcc-win easily because lcc-win
allows access to the real and imaginary parts of the complex
data type easily, using
z.re (real part)
and
ze.im

for the imaginary part.

I do not see how can be this written in standard C.
Has anyone an idea?
Just guessing, since I do not have a C99 compiler handy right now, but
I would say:

#include <complex.h>
double complex my_csqrt(double complex z)
{
double r;
r = sqrt(creal(z) * creal(z) + (cimag(z) * cimag(z)) * I;
r = sqrt(ldexp(r + fabs(creal(z)), -1));
if (r == 0.)
z= 0.0 + 0.0 * I;
else {
if (creal(z) >= 0.) {
z = r + ldexp(cimag(z) / r, -1) * I;
} else {
z = ldexp(fabs(cimag(z)) / r, -1) + cimag(z) >= 0 ? r *
I : -r * I;
}
}
return z;
}
Jan 24 '08 #3
jacob navia wrote:
hi

I am trying to use the complex data type.

Consider this code, taken from the cclib library:

struct complex csqrt(Cpx z)
{ double r;
r=sqrt(z.re*z.re+z.im*z.im);
r=sqrt(ldexp(r+fabs(z.re),-1));
if(r==0.) z.re=z.im=0.;
else{
if(z.re>=0.){ z.re=r; z.im=ldexp(z.im/r,-1);}
else{ z.re=ldexp(fabs(z.im)/r,-1);
if(z.im>=0.) z.im=r; else z.im= -r;
}
}
return z;
}

Now, this works in lcc-win easily because lcc-win
allows access to the real and imaginary parts of the complex
data type easily, using
z.re (real part)
and
ze.im

for the imaginary part.

I do not see how can be this written in standard C.
Has anyone an idea?
Your function works just fine in standard C. Check the following:
#include <math.h>
#include <stdio.h>

/* if you don't have <complex.h>, remove or comment out the line below */
#define USE_COMPLEX_H

typedef struct cmplx
{
double re, im;
} Cpx;
/* 'cmplx' chosen for the name of the struct since 'complex' should be
<complex.h*/

Cpx Csqrt
/* renamed because csqrt should be in <complex.h*/
(Cpx z)
{
double r;
r = sqrt(z.re * z.re + z.im * z.im);
r = sqrt(ldexp(r + fabs(z.re), -1));
if (r == 0.)
z.re = z.im = 0.;
else {
if (z.re >= 0.) {
z.re = r;
z.im = ldexp(z.im / r, -1);
}
else {
z.re = ldexp(fabs(z.im) / r, -1);
if (z.im >= 0.)
z.im = r;
else
z.im = -r;
}
}
return z;
}

Cpx Csquare(Cpx z)
{
Cpx r;
r.re = z.re * z.re - z.im * z.im;
r.im = 2 * z.re * z.im;
return r;
}

#if defined(USE_COMPLEX_H)
#include <complex.h>

double complex Csqrt2(double complex z)
{
double r;
r = sqrt(creal(z) * creal(z) + cimag(z) * cimag(z));
r = sqrt(ldexp(r + fabs(creal(z)), -1));
if (r == 0.)
z = 0.;
else {
if (creal(z) >= 0.) {
z = r + ldexp(cimag(z) / r, -1) * I;
}
else {
z = ldexp(fabs(cimag(z)) / r,
-1) + (cimag(z) >= 0. ? r : -r) * I;
}
}
return z;
}
#endif

int main(void)
{
Cpx x, y, z;
#if defined(USE_COMPLEX_H)
double complex cx, cy, cz;
#endif
int i, j;
printf("Using the function Jacob Navia provided,\n"
"with a struct for complex types.\n\n");
for (i = -2; i < 3; i++)
for (j = -2; j < 3; j++) {
x.re = i;
x.im = j;
y = Csqrt(x);
z = Csquare(y);
printf("y = Csqrt(%g+%gi)) = %g+%gi, y*y=%g+%gi\n",
x.re, x.im, y.re, y.im, z.re, z.im);
}

#if defined(USE_COMPLEX_H)
printf("\nUsing the function Jacob Navia provided,\n"
"rewritten to use complex types.\n\n");
for (i = -2; i < 3; i++)
for (j = -2; j < 3; j++) {
cx = i + j * I;
cy = Csqrt2(cx);
cz = cy * cy;
printf("y = Csqrt2(%g+%gi)) = %g+%gi, y*y=%g+%gi\n",
creal(cx), cimag(cx),
creal(cy), cimag(cy),
creal(cz), cimag(cz));
}

#endif

return 0;
}

[Output]

Using the function Jacob Navia provided,
with a struct for complex types.

y = Csqrt(-2+-2i)) = 0.643594+-1.55377i, y*y=-2+-2i
y = Csqrt(-2+-1i)) = 0.343561+-1.45535i, y*y=-2+-1i
y = Csqrt(-2+0i)) = 0+1.41421i, y*y=-2+0i
y = Csqrt(-2+1i)) = 0.343561+1.45535i, y*y=-2+1i
y = Csqrt(-2+2i)) = 0.643594+1.55377i, y*y=-2+2i
y = Csqrt(-1+-2i)) = 0.786151+-1.27202i, y*y=-1+-2i
y = Csqrt(-1+-1i)) = 0.45509+-1.09868i, y*y=-1+-1i
y = Csqrt(-1+0i)) = 0+1i, y*y=-1+0i
y = Csqrt(-1+1i)) = 0.45509+1.09868i, y*y=-1+1i
y = Csqrt(-1+2i)) = 0.786151+1.27202i, y*y=-1+2i
y = Csqrt(0+-2i)) = 1+-1i, y*y=0+-2i
y = Csqrt(0+-1i)) = 0.707107+-0.707107i, y*y=1.5702e-16+-1i
y = Csqrt(0+0i)) = 0+0i, y*y=0+0i
y = Csqrt(0+1i)) = 0.707107+0.707107i, y*y=1.5702e-16+1i
y = Csqrt(0+2i)) = 1+1i, y*y=0+2i
y = Csqrt(1+-2i)) = 1.27202+-0.786151i, y*y=1+-2i
y = Csqrt(1+-1i)) = 1.09868+-0.45509i, y*y=1+-1i
y = Csqrt(1+0i)) = 1+0i, y*y=1+0i
y = Csqrt(1+1i)) = 1.09868+0.45509i, y*y=1+1i
y = Csqrt(1+2i)) = 1.27202+0.786151i, y*y=1+2i
y = Csqrt(2+-2i)) = 1.55377+-0.643594i, y*y=2+-2i
y = Csqrt(2+-1i)) = 1.45535+-0.343561i, y*y=2+-1i
y = Csqrt(2+0i)) = 1.41421+0i, y*y=2+0i
y = Csqrt(2+1i)) = 1.45535+0.343561i, y*y=2+1i
y = Csqrt(2+2i)) = 1.55377+0.643594i, y*y=2+2i

Using the function Jacob Navia provided,
rewritten to use __complex__ types.

y = Csqrt2(-2+-2i)) = 0.643594+-1.55377i, y*y=-2+-2i
y = Csqrt2(-2+-1i)) = 0.343561+-1.45535i, y*y=-2+-1i
y = Csqrt2(-2+0i)) = 0+1.41421i, y*y=-2+0i
y = Csqrt2(-2+1i)) = 0.343561+1.45535i, y*y=-2+1i
y = Csqrt2(-2+2i)) = 0.643594+1.55377i, y*y=-2+2i
y = Csqrt2(-1+-2i)) = 0.786151+-1.27202i, y*y=-1+-2i
y = Csqrt2(-1+-1i)) = 0.45509+-1.09868i, y*y=-1+-1i
y = Csqrt2(-1+0i)) = 0+1i, y*y=-1+0i
y = Csqrt2(-1+1i)) = 0.45509+1.09868i, y*y=-1+1i
y = Csqrt2(-1+2i)) = 0.786151+1.27202i, y*y=-1+2i
y = Csqrt2(0+-2i)) = 1+-1i, y*y=0+-2i
y = Csqrt2(0+-1i)) = 0.707107+-0.707107i, y*y=1.5702e-16+-1i
y = Csqrt2(0+0i)) = 0+0i, y*y=0+0i
y = Csqrt2(0+1i)) = 0.707107+0.707107i, y*y=1.5702e-16+1i
y = Csqrt2(0+2i)) = 1+1i, y*y=0+2i
y = Csqrt2(1+-2i)) = 1.27202+-0.786151i, y*y=1+-2i
y = Csqrt2(1+-1i)) = 1.09868+-0.45509i, y*y=1+-1i
y = Csqrt2(1+0i)) = 1+0i, y*y=1+0i
y = Csqrt2(1+1i)) = 1.09868+0.45509i, y*y=1+1i
y = Csqrt2(1+2i)) = 1.27202+0.786151i, y*y=1+2i
y = Csqrt2(2+-2i)) = 1.55377+-0.643594i, y*y=2+-2i
y = Csqrt2(2+-1i)) = 1.45535+-0.343561i, y*y=2+-1i
y = Csqrt2(2+0i)) = 1.41421+0i, y*y=2+0i
y = Csqrt2(2+1i)) = 1.45535+0.343561i, y*y=2+1i
y = Csqrt2(2+2i)) = 1.55377+0.643594i, y*y=2+2i
Jan 25 '08 #4
jacob navia <ja***@nospam.comwrote:
In lcc-win it works since lcc-win defines
#define creal(z) z.re
Nitpick: you need
#define creal(z) ((z).re)

to avoid bad interactions with operators when z is an expression
and creal(z) is part of a larger expression.

(this apart from whether creal() can be implemented as a macro,
and whether the standard should provide direct accessors to the
members of a complex.)
--
pa at panix dot com
Jan 25 '08 #5
jacob navia wrote:
Army1987 wrote:
>z = creal(z) + I * new_imag_part;
z = new_real_part + I * cimag(z);

Well in the chapter "Awful syntax anyone?" that would
take the first prize...

Or maybe that's too harsh.

fn = (int *(*)(int))foo;

is maybe better
Afwulness is in the eye of the beholder.
I think I will keep my "extensions"

z.im = new_imag_part;

Easy isn't it?
I think that you're allowed to do that, as that couldn't break any strictly
conforming program.
Why do we have creal()z) (a "getter" function) and not setreal(z) (the
"setter" part)?
Yes, maybe that'be useful. (Of course that'd not be setreal(z)...)
--
Army1987 (Replace "NOSPAM" with "email")
Jan 25 '08 #6
Army1987 wrote:
jacob navia wrote:
>I think I will keep my "extensions"

z.im = new_imag_part;

Easy isn't it?
I think that you're allowed to do that, as that couldn't break any strictly
conforming program.
Not breaking strictly conforming programs is only one requirement of a
conforming implementation. Jacob's extension violates a constraint,
according to n1256 6.5.2.3p1. He's only allowed to do it provided he
issues a diagnostic in conforming mode.
>Why do we have creal()z) (a "getter" function) and not setreal(z) (the
"setter" part)?
Yes, maybe that'be useful. (Of course that'd not be setreal(z)...)
I can see the argument for it, though it's purely syntactic since

setreal(&z,real); /* or z = setreal(z,real); */

would be equivalent to

z = real + cimag(z)*I;

In fact I prefer the current version of doing things, because C's syntax
does not lend itself to setter functions (ie z.setreal(real) or
setreal(z,real) would not be possible.)
Jan 25 '08 #7
Philip Potter wrote:
Army1987 wrote:
>jacob navia wrote:
>>I think I will keep my "extensions"

z.im = new_imag_part;

Easy isn't it?
I think that you're allowed to do that, as that couldn't break any
strictly
conforming program.

Not breaking strictly conforming programs is only one requirement of a
conforming implementation. Jacob's extension violates a constraint,
according to n1256 6.5.2.3p1. He's only allowed to do it provided he
issues a diagnostic in conforming mode.
>>Why do we have creal()z) (a "getter" function) and not setreal(z) (the
"setter" part)?
Yes, maybe that'be useful. (Of course that'd not be setreal(z)...)

I can see the argument for it, though it's purely syntactic since

setreal(&z,real); /* or z = setreal(z,real); */

would be equivalent to

z = real + cimag(z)*I;

In fact I prefer the current version of doing things, because C's syntax
does not lend itself to setter functions (ie z.setreal(real) or
setreal(z,real) would not be possible.)
But why z.real and z.imaginary would be forbidden?

It is clear that complex are built from float/double/long double PAIRS.
Why couldn't we agree in the name of those elemnts of the pairs
and be done with it?

Writing

z.real = 5.887;

is Much clearer than

z = creal(z) + 5.887*I;

Besides, it requires a lot LESS implementation effort
than to recognize the first thing as its equivalent.

For a compiler is harder to recognize ALL the possible forms of the
first statement as equivalent

z = 5.887*I+creal(z);
z = (6.887-1.0)*I+creal(z);

etc etc etc!

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jan 25 '08 #8
Army1987 <ar******@nospam.itwrote:
Any function can be implemented as a macro, but it ought to be
#define creal(z) (((double _Complex)(z)).re)
as it should have the right type regardless of the type of z.
But then you lose the lvalue-preserving property. It looks like
there is no way to do what Jacob wanted without breaking the
conformance of creal(). Too bad.

Come to think of it, how is it done in Fortran ? The same way
as in C99, I think.
complex z
z= cmplx(new_real_val, imag(z))
z= cmplx(real(z), new_imag_val)

No direct accessors there either. To change one of the components
you have to synthesize a new complex number.

--
pa at panix dot com
Jan 26 '08 #9
user923005 wrote:
It could be implemented (for instance) as:

complex {
double parts[2];
};

or
complex {
double re;
double im;
};

or whatever underneath the covers, since that bit is not specified
clearly.
Of course it might be implemented as the standard specifies:
"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."
When you think about that, then I'm sure you will realize that there are
a number of ways to accomplish what you want.
Jan 26 '08 #10
On Jan 25, 9:01*pm, Martin Ambuhl <mamb...@earthlink.netwrote:
user923005 wrote:
It could be implemented (for instance) as:
complex {
double parts[2];
};
or
complex {
double re;
double im;
};
or whatever underneath the covers, since that bit is not specified
clearly.

Of course it might be implemented as the standard specifies:
"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."
When you think about that, then I'm sure you will realize that there are
a number of ways to accomplish what you want.
It's kind of sad if you are forced to do it in an underhanded way by
taking the address, though.
Jan 28 '08 #11
user923005 wrote:
On Jan 25, 9:01 pm, Martin Ambuhl <mamb...@earthlink.netwrote:
>user923005 wrote:
>>It could be implemented (for instance) as:
complex {
double parts[2];
};
or
complex {
double re;
double im;
};
or whatever underneath the covers, since that bit is not specified
clearly.
Of course it might be implemented as the standard specifies:
"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."
When you think about that, then I'm sure you will realize that there are
a number of ways to accomplish what you want.

It's kind of sad if you are forced to do it in an underhanded way by
taking the address, though.
Specially if it could have been so easy to specify a couple of "setter"
functions:

// For double _Complex
double sreal(complex,double); // Returns the old value
double simag(complex,double); // Returns the old value

that would do this!

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Jan 28 '08 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

34
by: Pmb | last post by:
I've been working on creating a Complex class for my own learning purpose (learn through doing etc.). I'm once again puzzled about something. I can't figure out how to overload the assignment...
3
by: Arthur | last post by:
Spending the morning avoiding responsibilities, and seeing what it would take to color some complex numbers. class color_complex(complex): def __init__(self,*args,**kws):...
7
by: Schüle Daniel | last post by:
Hello I am trying to customize the handling of complex numbers what I am missing is a builtin possibility to create complex numbers in polar coordinates so first I wrote a standalone function...
12
by: Russ | last post by:
I tried the following: >>> x = complex(4) >>> y = x >>> y *= 2 >>> print x, y (4+0j) (8+0j) But when I tried the same thing with my own class in place of "complex" above, I found that both...
2
by: jccorreu | last post by:
I'm taking in data from multiple files that represents complex numbers for charateristics of different elements. I begin with arrays of doubles and interpolate to get standard values in real and...
3
by: Klaas Vantournhout | last post by:
Hi, I am using CLAPACK to do lots of matrix operations, but this is done on complex matrices. There I also need to work with normal complex operators, I use also the standard complex library. ...
2
by: jraul | last post by:
Suppose you have a complex number class, and you overload conversions to double by only taking the real part. You also overload operator* to do complex multiplication. You then write: ...
3
by: katis | last post by:
Hi all :) Is it posible in xsd to change only minOccurs value of element in complex type by extending this type? The problem I'm trying to solve is this: I have two complex types -...
2
by: =?Utf-8?B?c2lwcHl1Y29ubg==?= | last post by:
Have a complex process where I need to Import a large amount of data then run some transformations on this data then import into DataBase. The transformation involves multiple fields and multiple...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.