Operations with complex numbers

F

fgg

Hi,

I'm doing some calculations involving complex numbers, but I'm not
getting the expected results. Does anyone see any problem with the
function below? Maybe there's nothing wrong with it (I could just be
using the wrong value for the parameter "x", for example). Just wanted
to make sure I'm doing it the right way.

All I need is to find the real and imaginary parts of the resulting
complex number, and compute amplitude and phase. e.g.

z = coherence(20, 0.16, 320);
printf("coherence = %g + %g * i\n", creal(z), cimag(z));
printf("amplitude = %.4f\n", cabs(z));
printf("phase = %.4f\n", carg(z));

/* function */
complex coherence(double a, double b, double c)
{
complex num, den;
double x;
num = x * b * cexp(I * c) * cexp(I * a) * exp(a * b) - 1;
den = (exp(a * b) - 1) * (I + b);
return num/den;
}

Thanks in advance!
 
I

Ike Naar

complex coherence(double a, double b, double c)
{
complex num, den;
double x;
num = x * b * cexp(I * c) * cexp(I * a) * exp(a * b) - 1;

The value of x is indeterminate.
 
F

fgg

Hi,

I'm doing some calculations involving complex numbers, but I'm not
getting the expected results. Does anyone see any problem with the
function below? Maybe there's nothing wrong with it (I could just be
using the wrong value for the parameter "x", for example). Just wanted
to make sure I'm doing it the right way.

All I need is to find the real and imaginary parts of the resulting
complex number, and compute amplitude and phase. e.g.

z = coherence(20, 0.16, 320);
printf("coherence = %g + %g * i\n", creal(z), cimag(z));
printf("amplitude = %.4f\n", cabs(z));
printf("phase = %.4f\n", carg(z));

/* function */
complex coherence(double a, double b, double c)
{
        complex num, den;
        double x;
        num = x * b * cexp(I * c) * cexp(I * a) * exp(a * b) - 1;
        den = (exp(a * b) - 1) * (I + b);
        return num/den;

}

Thanks in advance!

"double x;" doesn't really need to be there. I'm passing "x" as a
symbolic constant in the actual program.
 
I

Ike Naar

[...]
complex coherence(double a, double b, double c)
{
? ? ? ? complex num, den;
? ? ? ? double x;
? ? ? ? num = x * b * cexp(I * c) * cexp(I * a) * exp(a * b) - 1;
? ? ? ? den = (exp(a * b) - 1) * (I + b);
? ? ? ? return num/den;
}
[...]
"double x;" doesn't really need to be there. I'm passing "x" as a
symbolic constant in the actual program.

"doesn't really need to be there" ?
It should go away. It hides the symbolic constant defined
elsewhere in the program.
 
F

fgg

[...]
complex coherence(double a, double b, double c)
{
? ? ? ? complex num, den;
? ? ? ? double x;
? ? ? ? num = x * b * cexp(I * c) * cexp(I * a) * exp(a * b) - 1;
? ? ? ? den = (exp(a * b) - 1) * (I + b);
? ? ? ? return num/den;
}
[...]
"double x;" doesn't really need to be there. I'm passing "x" as a
symbolic constant in the actual program.

"doesn't really need to be there" ?
It should go away. It hides the symbolic constant defined
elsewhere in the program.

Sorry. What I meant was that it shouldn't be there. Here's the
corrected function:

/* function */
complex coherence(double a, double b, double c)
{
complex num, den;
num = x * b * cexp(I * c) * cexp(I * a) * exp(a * b) - 1;
den = (exp(a * b) - 1) * (I + b);
return num/den;

}
 
K

Keith Thompson

fgg said:
I'm doing some calculations involving complex numbers, but I'm not
getting the expected results. Does anyone see any problem with the
function below? Maybe there's nothing wrong with it (I could just be
using the wrong value for the parameter "x", for example). Just wanted
to make sure I'm doing it the right way.

All I need is to find the real and imaginary parts of the resulting
complex number, and compute amplitude and phase. e.g.

z = coherence(20, 0.16, 320);
printf("coherence = %g + %g * i\n", creal(z), cimag(z));
printf("amplitude = %.4f\n", cabs(z));
printf("phase = %.4f\n", carg(z));

/* function */
complex coherence(double a, double b, double c)
{
complex num, den;
double x;
num = x * b * cexp(I * c) * cexp(I * a) * exp(a * b) - 1;
den = (exp(a * b) - 1) * (I + b);
return num/den;
}

Please post a compilable self-contained program that demonstrates
the problem.

Presumably the statements are inside some function, perhaps main().
Adding a definition for main, plus the three required #include
directives, costs only a few lines and lets the rest of us try out
your program without having to fix it.

Assuming #include <complex.h>, "complex" by itself is not a valid
type name. You probably want "double complex". (gcc apparently
permits "complex" as an alias for "double complex" by default.
If you're using gcc, try compiling your code with "gcc -std=c99
-pedantic".)

Oh, and if you could tell us what output you expect and what your
program actually produces, that would be very helpful to those of
us who don't necessarily know what "coherence" means in this context.
 
F

fgg

Please post a compilable self-contained program that demonstrates
the problem.

Presumably the statements are inside some function, perhaps main().
Adding a definition for main, plus the three required #include
directives, costs only a few lines and lets the rest of us try out
your program without having to fix it.

Assuming #include <complex.h>, "complex" by itself is not a valid
type name.  You probably want "double complex".  (gcc apparently
permits "complex" as an alias for "double complex" by default.
If you're using gcc, try compiling your code with "gcc -std=c99
-pedantic".)

Oh, and if you could tell us what output you expect and what your
program actually produces, that would be very helpful to those of
us who don't necessarily know what "coherence" means in this context.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Hi Keith,

The actual program follows below. I'm using Apple's Xcode... maybe
that's the problem. I'll run it using "double complex" instead to see
if things change.

I wasn't expecting amplitudes > 1. That's what you get if you enter,
for example, hv = 15, z0 = 0, and sigmax = 0.3.

Thanks,
Fabio


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

#define B 5 /* baseline length [m] */
#define H 7980 /* altitude [m] */
#define LAMBDA 0.056 /* wavelength [m] */
#define THETA 35 /* look angle [degrees] */
#define DELTA 0 /* maybe 66.25? ... baseline angle [degrees] */
#define BW 40000000 /* bandwidth [Hz] */
#define C 299792458 /* speed of light [m/s] */

/* Declare coherence function */
complex coherence(double hv, double z0, double sigmaxdb);

/* Declare global variables */
double theta_rad, k, r1, alpha_z, ar, hv, z0, sigmaxdb;

int main()
{
/* Declare and define intermediate variables */
double delta_rad, alpha_r, range_res, a;
theta_rad = THETA * M_PI / 180;
delta_rad = DELTA * M_PI / 180;
k = 2 * M_PI / LAMBDA;
r1 = H / cos(theta_rad);
alpha_z = k * B * cos(theta_rad - delta_rad) / (r1 * sin(theta_rad));
alpha_r = k * B * cos(theta_rad - delta_rad) * cos(theta_rad) / (r1 *
sin(theta_rad));
range_res = C / (2 * BW);
a = 1 / r1;
ar = 1 - (alpha_r * range_res / (2 * M_PI));

/* Ask for model inputs */
printf("\nPlease input...\n");
printf("hv [m]: ");
scanf("%lf", &hv);
printf("z0 [m]: ");
scanf("%lf", &z0);
printf("sigmax [dB/m]: ");
scanf("%lf", &sigmaxdb);

/* Print results */
complex z;
z = coherence(hv, z0, sigmaxdb);
printf("\n-----------------------------\n");
printf("\ncoherence = %g + %g * i\n", creal(z), cimag(z));
printf("amplitude = %.4f\n", cabs(z));
printf("phase = %.4f\n", carg(z));
printf("\n-----------------------------\n");

return 0;
}

/* Define coherence function */
complex coherence(double hv, double z0, double sigmaxdb)
{
double sigmax, gamma, phi_0;
complex num, den;
sigmax = sigmaxdb * log(10) / 10;
gamma = 2 * sigmax / cos(theta_rad);
phi_0 = k * B * sin(acos((H - z0) / r1));
num = gamma * ar * cexp(I * phi_0) * cexp(I * alpha_z * hv) *
exp(gamma * hv) - 1;
den = (exp(gamma * hv) - 1) * (I * alpha_z + gamma);
return num/den;
}
 
N

Nobody

#define B 5 /* baseline length [m] */
#define H 7980 /* altitude [m] */
#define THETA 35 /* look angle [degrees] */
#define DELTA 0 /* maybe 66.25? ... baseline angle [degrees] */
#define BW 40000000 /* bandwidth [Hz] */
#define C 299792458 /* speed of light [m/s] */

I suggest changing all of the above values from integers to floating-point.

Dividing the above constants by each other will use integer division
(truncating to an integer result), while multiplying BW or C may cause
integer overflow.
 
F

fgg

Hi Keith,
The actual program follows below. I'm using Apple's Xcode... maybe
that's the problem. I'll run it using "double complex" instead to see
if things change.
I wasn't expecting amplitudes > 1. That's what you get if you enter,
for example, hv = 15, z0 = 0, and sigmax = 0.3.

#include <stdio.h>
#include <math.h>
#include <complex.h>
#define B 5             /* baseline length [m] */
#define H 7980          /* altitude [m] */
#define LAMBDA 0.056    /* wavelength [m] */
#define THETA 35        /* look angle [degrees] */
#define DELTA 0         /* maybe 66.25? ... baseline angle [degrees] */
#define BW 40000000     /* bandwidth [Hz] */
#define C 299792458     /* speed of light [m/s] */
/* Declare coherence function */
complex coherence(double hv, double z0, double sigmaxdb);
/* Declare global variables */
double theta_rad, k, r1, alpha_z, ar, hv, z0, sigmaxdb;
int main()
{
        /* Declare and define intermediate variables */
        double delta_rad, alpha_r, range_res, a;
        theta_rad = THETA * M_PI / 180;
        delta_rad = DELTA * M_PI / 180;
        k = 2 * M_PI / LAMBDA;
        r1 = H / cos(theta_rad);
        alpha_z = k * B * cos(theta_rad - delta_rad) / (r1 * sin(theta_rad));
        alpha_r = k * B * cos(theta_rad - delta_rad) * cos(theta_rad) / (r1 *
sin(theta_rad));
        range_res = C / (2 * BW);
        a = 1 / r1;
        ar = 1 - (alpha_r * range_res / (2 * M_PI));
        /* Ask for model inputs */
        printf("\nPlease input...\n");
        printf("hv [m]: ");
        scanf("%lf", &hv);
        printf("z0 [m]: ");
        scanf("%lf", &z0);
        printf("sigmax [dB/m]: ");
        scanf("%lf", &sigmaxdb);
        /* Print results */
        complex z;
        z = coherence(hv, z0, sigmaxdb);
        printf("\n-----------------------------\n");
        printf("\ncoherence = %g + %g * i\n", creal(z), cimag(z));
        printf("amplitude = %.4f\n", cabs(z));
        printf("phase = %.4f\n", carg(z));
        printf("\n-----------------------------\n");
        return 0;

/* Define coherence function */
complex coherence(double hv, double z0, double sigmaxdb)
{
        double sigmax, gamma, phi_0;
        complex num, den;
        sigmax = sigmaxdb * log(10) / 10;
        gamma = 2 * sigmax / cos(theta_rad);
        phi_0 = k * B * sin(acos((H - z0) / r1));
        num = gamma * ar * cexp(I * phi_0) * cexp(I * alpha_z * hv) *
exp(gamma * hv) - 1;
        den = (exp(gamma * hv) - 1) * (I * alpha_z + gamma);
        return num/den;

You could set a breakpoint at the call to coherence, step through your
code, and watch how the numbers change, then check where something is
different than intended. It's called debugging.

Better yet, set a breakpoint at the beginning of main and watch
_carefully_ what values the constants take that you calculate. You
might also check the rules for integer division.

Thanks, Christian. Do you have a reference for the rules? (maybe a
website?)

Nobody, is this what you mean?

#define B 5.0 /* baseline length [m] */
#define H 7980.0 /* altitude [m] */
#define LAMBDA 0.056 /* wavelength [m] */
#define THETA 35.0 /* look angle [degrees] */
#define DELTA 0.0 /* maybe 66.25? ... baseline angle [degrees]
*/
#define BW 40000000.0 /* bandwidth [Hz] */
#define C 299792458.0 /* speed of light [m/s] */

Should I do the same with the other constants? As in

a = 1.0 / r1;

or this won't help?

Thanks
 
I

Ian Collins

On 10/26/10 11:59 AM, fgg wrote:

Trimming is good!
Thanks, Christian. Do you have a reference for the rules? (maybe a
website?)

The standard is a good, if heavy place to start. Google gives some good
results.
Nobody, is this what you mean?

#define B 5.0 /* baseline length [m] */

Why not be explicit?

const double H = 7980.0;

Or explicit and useful:

const double altitude = 7980.0;
#define H 7980.0 /* altitude [m] */
#define LAMBDA 0.056 /* wavelength [m] */
#define THETA 35.0 /* look angle [degrees] */
#define DELTA 0.0 /* maybe 66.25? ... baseline angle [degrees]
*/
#define BW 40000000.0 /* bandwidth [Hz] */
#define C 299792458.0 /* speed of light [m/s] */

Should I do the same with the other constants? As in

a = 1.0 / r1;

It doesn't hurt. The reader has on less thing the consider. While you
are there, make them const if they are intended as constants:

const double a = 1.0 / r1;
 
A

Alan Curry

The actual program follows below. I'm using Apple's Xcode... maybe
that's the problem. I'll run it using "double complex" instead to see
if things change.

I don't know what these equations are all about, but this one looks
odd to me:
num = gamma * ar * cexp(I * phi_0) * cexp(I * alpha_z * hv) *
exp(gamma * hv) - 1;

A bunch of things are multiplied together, some of which are complex, so the
result will be complex, then you're subtracting the real number 1. Is that
really what you meant?

Attempting dimensional analysis on it (which may have been a dumb idea),
I find that gamma has dimension 1/length, and the rest of the things being
multiplied are dimensionless, so you're subtracting the literal 1 from a
1/length quantity, meaning the literal 1 is 1/m or something similar, in the
direction of the real axis. That could be right, but sure sounds fishy given
the general lack of magic numbers elsewhere in the code.
 
G

Geoff

/* Define coherence function */
complex coherence(double hv, double z0, double sigmaxdb)
{
double sigmax, gamma, phi_0;
complex num, den;
sigmax = sigmaxdb * log(10) / 10;
gamma = 2 * sigmax / cos(theta_rad);
phi_0 = k * B * sin(acos((H - z0) / r1));
num = gamma * ar * cexp(I * phi_0) * cexp(I * alpha_z * hv) *
exp(gamma * hv) - 1;
den = (exp(gamma * hv) - 1) * (I * alpha_z + gamma);
return num/den;
}


Write a test harness for the coherence function, for a given set of
input values what are the expected and actual intermediate and output
values?

It seems your main function is that but where are your expected
results?

For instance, what does an HP48 return for your example inputs?
 
F

fgg

I don't know what these equations are all about, but this one looks
odd to me:


A bunch of things are multiplied together, some of which are complex, so the
result will be complex, then you're subtracting the real number 1. Is that
really what you meant?

Attempting dimensional analysis on it (which may have been a dumb idea),
I find that gamma has dimension 1/length, and the rest of the things being
multiplied are dimensionless, so you're subtracting the literal 1 from a
1/length quantity, meaning the literal 1 is 1/m or something similar, in the
direction of the real axis. That could be right, but sure sounds fishy given
the general lack of magic numbers elsewhere in the code.

Bingo! Everything after the first complex number should be enclosed in
parentheses:

num = gamma * ar * cexp(I * phi_0) * (cexp(I * alpha_z * hv) *
exp(gamma * hv) - 1);

This seems to solve the problem. Thanks for all suggestions!
 
F

fgg

The calculator, sure. I thought it was some kind of jargon term
related to C.

Keith, just when I was starting to like you! Should I send you my
instructor's email address again? :)
 
G

Geoff

The calculator, sure. I thought it was some kind of jargon term
related to C.

Keith, just when I was starting to like you! Should I send you my
instructor's email address again? :)

I would have thought anyone doing scientific work would keep his HP
close at hand. I carry mine in my laptop bag when I travel. I'm quite
rusty with it lately, but it's never very far away in an emergency. I
haven't tried any of the emulators though. I would think that it would
be a must-have for verification of equations like yours.

I suppose you could write it in WolframAlpha now.

My first year of college it was slipsticks and by the second year if
you didn't have a TI or HP your were left in the dust.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top