Complex waves in function

Hi,

A strange issue with complex waves.

The following codes :

Function test()
wave r12, m
 
wave ref1=r12
wave ref2=m
 
ref1=ref2
End

does not work. => "While executing a wave assignment, the following error occurred: Complex wave used in real expression."

but the following :

Macro titi()
r12=m
end

is fine.

These are two simple examples, my original program includes several calculations with complex waves.

Thanks a lot for your help.

In your function use wave /c r12 when you reference them.  The flag /c identifies them as complex.

 

Andy 

All the WAVE statements need to be WAVE/C if the waves referred are complex. If something doesn't work, please post the code that doesn't work, and details about the waves.

The difference between the macro and the function is that since a macro is interpreted at run-time, it will look up the actual waves involved and use the correct branch of code to deal with the actual wave type. A function must compile either complex or real code at a time when the wave may not even exist yet. So you have to tell the compiler what kind of code to compile. There is a run-time check to make sure the actual wave matches what you told the compiler. That avoids crashes.

Below are the two codes : one with the function, the other one as a macro. The macro works. Note that in the function code, the declared waves are real.

Function Calculate_T_F_plus_W()
wave n, k, wavenumber // n, k and wavenumber are real waves
variable e_f, e_w
variable /c ci
 
make /O /N=(numpnts(n)) /C m
m=cmplx(n,k)
 
duplicate /O wavenumber lambda
lambda=10000/wavenumber
 
duplicate /O lambda T_f
duplicate /O lambda T_w
duplicate /O lambda T_total
duplicate /O k alpha
duplicate /O k n_0
duplicate /O k n_i
duplicate /O k n_S
 
duplicate /O m delta
duplicate /O m r12
duplicate /O m t12 
duplicate /O m r23
duplicate /O m t23 
duplicate /O m r34
duplicate /O m t34
 
 
 
e_F=30 // µm
e_w=3000 // µm
n_0=1.5; n_s=1; n_i=1
 
ci=sqrt(-1)
 
r12=(n_i-m)/(n_i+m)
t12=2*n_i/(n_i+m)
 
r23=(m-n_0)/(m+n_0)
t23=2*m/(m+n_0)
 
r34=(n_0-n_s)/(n_0+n_s)
t34=2*n_0/(n_0+n_s)
 
k=imag(m)
n=real(m)
alpha=4*pi*k/lambda
delta=(2*pi/lambda)*m*e_f
 
/// Transmission film
T_f=(cabs(t12)^2*cabs(t23)^2*exp(-2*alpha*e_f))/cabs(1+r12*r23*exp(2*ci*delta))^2
 
/// Transmission winidow
T_w=cabs(t34)^2
 
/// Transmission total
T_total=T_f*T_w
 
 
End
 
 
 
Macro Calculate_TRANSMITTANCE_FILM_WINDOW()
variable e_f, e_w
variable /C ci
 
make /O /N=(numpnts(n)) /C m
m=cmplx(n,k)
 
duplicate /O wavenumber lambda
lambda=10000/wavenumber
 
duplicate /O lambda T_f
duplicate /O lambda T_w
duplicate /O lambda T_total
duplicate /O k alpha
duplicate /O k n_0
duplicate /O k n_i
duplicate /O k n_S
 
duplicate /O m delta
duplicate /O m r12
duplicate /O m t12 
duplicate /O m r23
duplicate /O m t23 
duplicate /O m r34
duplicate /O m t34
 
 
e_F=10 // µm
e_w=3000 // µm
n_0=1.5; n_s=1; n_i=1
 
ci=sqrt(-1)
 
r12=(n_i-m)/(n_i+m)
t12=2*n_i/(n_i+m)
 
r23=(m-n_0)/(m+n_0)
t23=2*m/(m+n_0)
 
r34=(n_0-n_s)/(n_0+n_s)
t34=2*n_0/(n_0+n_s)
 
k=imag(m)
n=real(m)
alpha=4*pi*k/lambda
delta=(2*pi/lambda)*m*e_f
 
/// Transmission film
T_f=(cabs(t12)^2*cabs(t23)^2*exp(-2*alpha*e_f))/cabs(1+r12*r23*exp(2*ci*delta))^2
 
/// Transmission window
T_w=cabs(t34)^2
 
/// Transmission total
T_total=T_f*T_w
 
 
End

 

Finally I fixed it, but not sure I understand why it works now.

 

the last version :

 

Function Calculate_T_F_plus_W()
wave n, k, wavenumber
variable e_f, e_w
variable /c ci
 
make /O /N=(numpnts(n)) /C m
make /O /N=(numpnts(n)) /C n_0
make /O /N=(numpnts(n)) /C n_i
make /O /N=(numpnts(n)) /C n_s
make /O /N=(numpnts(n)) /C delta
make /O /N=(numpnts(n)) /C r12
make /O /N=(numpnts(n)) /C t12 
make /O /N=(numpnts(n)) /C r23
make /O /N=(numpnts(n)) /C t23 
make /O /N=(numpnts(n)) /C r34
make /O /N=(numpnts(n)) /C t34
make /O /N=(numpnts(n)) alpha
 
duplicate /O wavenumber lambda
duplicate /O wavenumber T_f
duplicate /O wavenumber T_w
duplicate /O wavenumber T_total
 
m=cmplx(n,k)
lambda=10000/wavenumber
e_F=30 // µm
e_w=3000 // µm
n_0=cmplx(1.5,0)
n_s=cmplx(1,0)
n_i=cmplx(1,0)
 
ci=sqrt(-1)
r12=(n_i-m)/(n_i+m)
t12=2*n_i/(n_i+m)
 
r23=(m-n_0)/(m+n_0)
t23=2*m/(m+n_0)
 
r34=(n_0-n_s)/(n_0+n_s)
t34=2*n_0/(n_0+n_s)
 
 
alpha=4*pi*k/lambda
delta=(2*pi/lambda)*m*e_f
 
/// Transmission du film
T_f=(cabs(t12)^2*cabs(t23)^2*exp(-2*alpha*e_f))/cabs(1+r12*r23*exp(2*ci*delta))^2
 
/// Transmission de la fenêtre
T_w=cabs(t34)^2
 
/// Transmission totle
T_total=T_f*T_w
 
 
 
End

 

Your fix of adding /C to the Make commands is the correct one: The compiler now knows that the created waves will be complex at runtime, and compiles code that expects and operates on complex waves.

OK. So it means that the the command:

duplicate /O m delta

should write:

duplicate /O /C m delta

?

Only if you want to use the automatic wave assignment created by the duplicate operation. The duplicate operation alone will work just fine without this flag. You seem to be confused by these flags, but it is very simple actually. You have to let Igor (the compiler) know what type of data you are working with (if you want to work with the data via wave assignments etc.), so that type conflicts are avoided. It would surely be useless to feed a numerical wave some text like 'Hello', no? So if Igor does not know you are using complex waves, it will treat the thing as the default, which are just numbers and will lead to the error. You can read more about this here:

DisplayHelpTopic "WAVE Reference Types"

I recommend to avoid macros at all costs.

Hi Erik,

I'm new at WaveMetrics and also found parts of this confusing. I went through the first code you submitted and made the minimal number of changes required to get it working. The changes are all commented. Hopefully this will help you understand the nuances of the Duplicate command a bit better. At least, it helped me :)

 

Function Calculate_T_F_plus_W()
    wave n, k, wavenumber // n, k and wavenumber are real waves
    variable e_f, e_w
    variable /c ci
 
    make /O /N=(numpnts(n)) /c m
    m=cmplx(n,k)
 
    duplicate /O wavenumber lambda
    lambda=10000/wavenumber
 
    duplicate /O lambda T_f
    duplicate /O lambda T_w
    duplicate /O lambda T_total
    duplicate /O k alpha
 
    // Added /C to the following 8 Duplicate calls
    // Wave data type and Wave reference data type will both be complex
    duplicate /O/C k n_0
    duplicate /O/C k n_i
    duplicate /O/C k n_s
 
    duplicate /O /c m delta
    duplicate /O /c m r12
    duplicate /O /c m t12 
    duplicate /O /c m r23
    duplicate /O /c m t23 
 
    // r34 and t34 don't need to be complex
    // Duplicate call makes a complex wave but a real wave reference
    // Redimension call makes the wave data type also real
    duplicate /O m r34
    Redimension /r r34
    duplicate /O m t34
    Redimension /r t34
 
    e_F=30 // µm
    e_w=3000 // µm
    n_0=1.5; n_s=1; n_i=1
 
    ci=sqrt(-1)
 
    r12=(n_i-m)/(n_i+m)
    t12=2*n_i/(n_i+m)
  
    r23=(m-n_0)/(m+n_0)
    t23=2*m/(m+n_0)
 
    r34=(n_0-n_s)/(n_0+n_s)
    t34=2*n_0/(n_0+n_s)
 
    k=imag(m)
    n=real(m)
    alpha=4*pi*k/lambda
    delta=(2*pi/lambda)*m*e_f
 
    /// Transmission film
    T_f=(cabs(t12)^2*cabs(t23)^2*exp(-2*alpha*e_f))/cabs(1+r12*r23*exp(2*ci*delta))^2
 
    /// Transmission window
    // abs function can be real
    T_w=abs(t34)^2
 
    /// Transmission total
    T_total=T_f*T_w
End

Thanks,

Kris

Hi Kris

Thanks a lot for your comments. Really helpful :

   // Duplicate call makes a complex wave but a real wave reference"

Here is the explanation and explains why it worked when I removed the duplicate and replaced them with Make /C.

Cheers,

Eric