Top Banner
Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction m of the sphere may be complex, m = n(1 - ) The imaginary part of the complex refractive index is the damping factor while κ is called the index of absorption or the index of attenuation. Note that the sign of the imaginary part of the index of refraction is negative. The complex index of refraction may also be written in terms of the conductivity σ, the dielectric constant ε and the circular frequency ω as m = r ε - i 4πσ ω The other important parmeter governing scattering by a sphere is the size parameter x of the sphere, which is given by x =2πa/λ Sometimes the value ρ is used to indicate the size of the sphere and it is defined as ρ =2x(m - 1) and really only makes sense if the sphere does not absorb light. The absorption coefficient from Beer’s law is defined as I = I 0 exp(-μ a z) and thus μ a = 4πnκ λ 0 = 4πκ λ where λ 0 is the wavelength in a vacuum [Kerker, p. 15]. Now to reprise some nomenclature. The extinction efficiency may be separated into Q ext = Q sca + Q abs where Q sca is the scattering efficiency and Q abs is the absorption efficiency. Typically Q sca and Q ext are determined by the Mie scattering program and Q abs is obtained by subtraction. The radiation pressure is given by Q pr = Q ext - gQ sca The pressure exerted on the particle of cross-sectional area πr 2 0 is P = F πr 2 0 = Q ext c were c is the velocity of the radiation in the medium [Kerker, p. 94].
58

Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

May 29, 2018

Download

Documents

dangthuy
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1

1. Equations for Mie scattering.The index of refraction m of the sphere may be complex,

m = n(1− iκ)

The imaginary part of the complex refractive index nκ is the damping factor while κ is calledthe index of absorption or the index of attenuation. Note that the sign of the imaginary part ofthe index of refraction is negative. The complex index of refraction may also be written in termsof the conductivity σ, the dielectric constant ε and the circular frequency ω as

m =

√ε− i4πσ

ω

The other important parmeter governing scattering by a sphere is the size parameter x of thesphere, which is given by

x = 2πa/λ

Sometimes the value ρ is used to indicate the size of the sphere and it is defined as

ρ = 2x(m− 1)

and really only makes sense if the sphere does not absorb light.The absorption coefficient from Beer’s law is defined as

I = I0 exp(−µaz)

and thusµa =

4πnκλ0

=4πκλ

where λ0 is the wavelength in a vacuum [Kerker, p. 15].Now to reprise some nomenclature. The extinction efficiency may be separated into

Qext = Qsca +Qabs

where Qsca is the scattering efficiency and Qabs is the absorption efficiency. Typically Qsca andQext are determined by the Mie scattering program and Qabs is obtained by subtraction.

The radiation pressure is given by

Qpr = Qext − gQsca

The pressure exerted on the particle of cross-sectional area πr20 is

P =F

πr20

=Qextc

were c is the velocity of the radiation in the medium [Kerker, p. 94].

Page 2: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

2 Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING

The relation between the efficiency factor for scattering and the cross section for scattering areobtained by dividing by the actual geometrical cross section

Qsca =Cscaπr2

0

where r0 is the radius of the sphere.The scattering cross section may be related to the transmission of a beam through a dispersion

of scatterers of equal size. For ρ particles per unit volume, the attenuation due to scattering is

−dIdx

= ρCscaI

The transmission isT = I/I0 = exp(−ρCscax) = exp(−µsx)

orµs = ρCsca = ρπr2

0Qsca

[Kerker, p. 38].

Page 3: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): DOUBLE ARRAY ROUTINES 3

2. Double Array Routines.Here are a bunch of routines to deal arrays of doubles. This file will create three files when

run through ctangle — the usual .c and .h, as well as a testing driver.

3. Here, then, is an overview of document structure〈 array.c 3 〉 ≡#include <stdlib.h>

#include <string.h>

#include <stdio.h>

#include <float.h>

#include "array.h"

〈Definition for array error 7 〉〈Definition for new darray 9 〉〈Definition for free darray 11 〉〈Definition for copy darray 13 〉〈Definition for set darray 15 〉〈Definition for min max darray 17 〉〈Definition for sort darray 20 〉〈Definition for print darray 23 〉

4. Each function has its prototype exported to a header file.〈 array.h 4 〉 ≡〈Prototype for new darray 8 〉;〈Prototype for free darray 10 〉;〈Prototype for copy darray 12 〉;〈Prototype for set darray 14 〉;〈Prototype for min max darray 16 〉;〈Prototype for sort darray 19 〉;〈Prototype for print darray 22 〉;

Page 4: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

4 Mie Scattering (Version 1.0): ALLOCATION

5. Allocation.

6. A simple error routine.〈Prototype for array error 6 〉 ≡

static void array error (char ∗s)This code is used in section 7.

7. 〈Definition for array error 7 〉 ≡〈Prototype for array error 6 〉{

printf ("Array −− %s\n", s);exit (1);

}This code is used in section 3.

copy darray : double ∗, §12.exit , <stdlib.h>.free darray : void, §10.

min max darray : void, §16.new darray : double ∗, §8.print darray : void, §22.

printf , <stdio.h>.set darray : void, §14.sort darray : void, §19.

Page 5: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): DOUBLE ARRAY ROUTINES 5

8. Double array routines.〈Prototype for new darray 8 〉 ≡

double ∗new darray (long size )

This code is used in sections 4 and 9.

9. 〈Definition for new darray 9 〉 ≡〈Prototype for new darray 8 〉{

double ∗a;

if (size ≤ 0) array error ("Non−positive double array size chosen");size += 2;a = (double ∗) malloc(sizeof (double) ∗ size );if (a ≡ Λ) array error ("Insufficient space to allocate array");a[0] = DBL_MIN;a[size − 1] = DBL_MAX;return a+ 1;

}This code is used in section 3.

10. 〈Prototype for free darray 10 〉 ≡void free darray (double ∗a)

This code is used in sections 4 and 11.

11. 〈Definition for free darray 11 〉 ≡〈Prototype for free darray 10 〉{

if (a 6= Λ) free (a− 1);}

This code is used in section 3.

12. This allocates a new double array data structure and copies the contents of a into it.〈Prototype for copy darray 12 〉 ≡

double ∗copy darray (double ∗a, long size )

This code is used in sections 4 and 13.

13. 〈Definition for copy darray 13 〉 ≡〈Prototype for copy darray 12 〉{

double ∗b = Λ;

if (a ≡ Λ) return b;b = new darray (size + 2);if (b ≡ Λ) array error ("Insufficient space to duplicate array");memcpy (b, a− 1, sizeof (double) ∗ (size + 2));return b+ 1;

}This code is used in section 3.

Page 6: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

6 Mie Scattering (Version 1.0): DOUBLE ARRAY ROUTINES

14. This sets all the entries in the array a[ ] to x.〈Prototype for set darray 14 〉 ≡

void set darray (double ∗a, long size ,double x)

This code is used in sections 4 and 15.

15. 〈Definition for set darray 15 〉 ≡〈Prototype for set darray 14 〉{

long j;

if (a ≡ Λ) array error ("Attempt to set elements in a NULL array");for (j = 0; j < size ; j++) a[j] = x;

}This code is used in section 3.

16. min max darray finds the minimum and maximum of the array a.〈Prototype for min max darray 16 〉 ≡

void min max darray (double ∗a, long size ,double ∗min ,double ∗max )

This code is used in sections 4 and 17.

17. 〈Definition for min max darray 17 〉 ≡〈Prototype for min max darray 16 〉{

long j;

if (a ≡ Λ) array error ("A NULL array does not have a min or max");if (size ≡ 0) array error ("An array with no elements does not have a min or max");∗min = a[0];∗max = ∗min ;for (j = 1; j < size ; j++) {

if (a[j] > ∗max ) ∗max = a[j];if (a[j] < ∗min ) ∗min = a[j];

}}

This code is used in section 3.

array error : static void, §6.DBL_MAX, <float.h>.

DBL_MIN, <float.h>.free : ???, §0.

malloc : ???, §0.memcpy , <string.h>.

Page 7: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): SORTING 7

18. Sorting.

19. sort darray will sort an array a into ascending numerical order using the Heapsort algo-rithm. Adapted to work with zero-based arrays from Numerical Recipes. This could certainlyuse some sprucing up, but I can’t quite seem to figure out how to do it. It is kinda tricky.〈Prototype for sort darray 19 〉 ≡

void sort darray (double ∗a, long size )

This code is used in sections 4 and 20.

20. 〈Definition for sort darray 20 〉 ≡〈Prototype for sort darray 19 〉{

long i, ir , j, l;double aa ;

if (a ≡ Λ) array error ("Can’t sort a NULL array");if (size < 2) return;l = (size � 1) + 1;ir = size ;for ( ; ; ) {

if (l > 1) {aa = a[−−l − 1];

}else {

aa = a[ir − 1];a[ir − 1] = a[0];if (−−ir ≡ 1) {a[0] = aa ;break;

}}i = l;j = l + l;while (j ≤ ir ) {

if (j < ir ∧ a[j − 1] < a[j]) j++;if (aa < a[j − 1]) {a[i− 1] = a[j − 1];i = j;j �= 1;

}else j = ir + 1;

}a[i− 1] = aa ;

}}

This code is used in section 3.

Page 8: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

8 Mie Scattering (Version 1.0): PRINTING

21. Printing.

22. print darray prints the elements of the array a from ilow through ihigh .〈Prototype for print darray 22 〉 ≡

void print darray (double ∗a, long size , long ilow , long ihigh )

This code is used in sections 4 and 23.

23. 〈Definition for print darray 23 〉 ≡〈Prototype for print darray 22 〉{

long j;

if (a ≡ Λ) array error ("Can’t print a NULL array");if (ilow < 0) ilow = 0;if (ihigh > size − 1) ihigh = size − 1;for (j = ilow ; j ≤ ihigh ; j++) printf ("x[%ld]= %−10.5g \n", j, a[j]);

}This code is used in section 3.

array error : static void, §6. printf , <stdio.h>.

Page 9: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): TESTING 9

24. Testing.

25. Here are driver routines to test the routines in this file.〈 arraytest.c 25 〉 ≡#include <stdio.h>

#include "array.h"

void main ( ){

double ∗x;double ∗y;long i, size ;double min , max ;

size = 10;printf ("starting\n");fflush (stdout );x = new darray (size );〈Test Set Routine 26 〉〈Test Copy Routine 27 〉〈Test Sort Routine 28 〉〈Test Min/Max Routine 29 〉printf ("done\n");fflush (stdout );

}

26. 〈Test Set Routine 26 〉 ≡printf ("Testing set_darray\n");printf ("All entries should be 3.0\n");set darray (x, size , 3.0);print darray (x, size , 0, size − 1);fflush (stdout );printf ("\n");

This code is used in section 25.

27. 〈Test Copy Routine 27 〉 ≡printf ("Testing copy_darray\n");for (i = 0; i < size ; i++) x[i] = size − i;printf ("The original vector was:\n");print darray (x, size , 0, size − 1);fflush (stdout );y = copy darray (x, size );printf ("The copied vector is:\n");print darray (y, size , 0, size − 1);fflush (stdout );printf ("\n");

This code is used in section 25.

28. 〈Test Sort Routine 28 〉 ≡printf ("Testing sort_darray\n");printf ("The original vector is:\n");

Page 10: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

10 Mie Scattering (Version 1.0): TESTING

print darray (x, size , 0, size − 1);fflush (stdout );sort darray (x, size );printf ("The sorted vector is:\n");print darray (x, size , 0, size − 1);fflush (stdout );printf ("\n");

This code is used in section 25.

29. 〈Test Min/Max Routine 29 〉 ≡printf ("Testing min_max_darray\n");min max darray (x, size ,&min ,&max );printf ("min=%g max=%g\n",min ,max );fflush (stdout );printf ("\n");

This code is used in section 25.

copy darray : double ∗, §12.fflush , <stdio.h>.min max darray : void, §16.

new darray : double ∗, §8.print darray : void, §22.printf , <stdio.h>.

set darray : void, §14.sort darray : void, §19.stdout , <stdio.h>.

Page 11: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): COMPLEX NUMBER ROUTINES 11

30. Complex Number Routines.Here are a bunch of routines to deal with complex numbers. The functions are pretty straight-

forward, but there are some subtle points in some of the functions. This could use some moreerror checking.

31. Here, then, is an overview of document structure〈 complex.c 31 〉 ≡#include <math.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <float.h>

#include "complex.h"

〈Definition for complex error 35 〉〈Definition for cset 37 〉〈Definition for cpolarset 39 〉〈Definition for cabs 41 〉〈Definition for carg 45 〉〈Definition for cnorm 47 〉〈Definition for csqrt 49 〉〈Definition for csqr 51 〉〈Definition for cinv 53 〉〈Definition for conj 43 〉〈Definition for cadd 56 〉〈Definition for csub 58 〉〈Definition for cmul 60 〉〈Definition for cdiv 62 〉〈Definition for crdiv 64 〉〈Definition for crmul 66 〉〈Definition for csadd 71 〉〈Definition for csdiv 73 〉〈Definition for csmul 69 〉〈Definition for csin 76 〉〈Definition for ccos 78 〉〈Definition for ctan 80 〉〈Definition for casin 82 〉〈Definition for cacos 84 〉〈Definition for catan 86 〉〈Definition for csinh 91 〉〈Definition for ccosh 89 〉〈Definition for ctanh 93 〉〈Definition for catanh 95 〉〈Definition for casinh 97 〉〈Definition for cexp 100 〉〈Definition for clog 102 〉〈Definition for clog10 104 〉〈Definition for new carray 107 〉〈Definition for free carray 109 〉

Page 12: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

12 Mie Scattering (Version 1.0): COMPLEX NUMBER ROUTINES

〈Definition for copy carray 111 〉〈Definition for set carray 113 〉

cabs : double, §40.cacos : struct complex, §83.cadd : struct complex, §55.carg : double, §44.casin : struct complex, §81.casinh : struct complex, §96.catan : struct complex, §85.catanh : struct complex, §94.ccos : struct complex, §77.ccosh : struct complex, §88.cdiv : struct complex, §61.cexp : struct complex, §99.cinv : struct complex, §52.

clog : struct complex, §101.clog10 : struct complex, §103.cmul : struct complex, §59.cnorm : double, §46.complex error : static void, §34.conj : struct complex, §42.copy carray : struct complex ∗,§110.

cpolarset : struct complex, §38.crdiv : double, §63.crmul : double, §65.csadd : struct complex, §70.csdiv : struct complex, §72.

cset : struct complex, §36.csin : struct complex, §75.csinh : struct complex, §90.csmul : struct complex, §68.csqr : struct complex, §50.csqrt : struct complex, §48.csub : struct complex, §57.ctan : struct complex, §79.ctanh : struct complex, §92.free carray : void, §108.new carray : struct complex ∗,§106.

set carray : void, §112.

Page 13: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): COMPLEX NUMBER ROUTINES 13

32. Each function has its prototype exported to a header file along with a couple of structuredefinitions.〈 complex.h 32 〉 ≡

struct complex {double re , im ;

};〈Prototype for cset 36 〉;〈Prototype for cpolarset 38 〉;〈Prototype for cabs 40 〉;〈Prototype for carg 44 〉;〈Prototype for csqr 50 〉;〈Prototype for conj 42 〉;〈Prototype for cnorm 46 〉;〈Prototype for csqrt 48 〉;〈Prototype for cinv 52 〉;〈Prototype for cadd 55 〉;〈Prototype for csub 57 〉;〈Prototype for cmul 59 〉;〈Prototype for cdiv 61 〉;〈Prototype for crdiv 63 〉;〈Prototype for crmul 65 〉;〈Prototype for csadd 70 〉;〈Prototype for csdiv 72 〉;〈Prototype for csmul 68 〉;〈Prototype for csin 75 〉;〈Prototype for ccos 77 〉;〈Prototype for ctan 79 〉;〈Prototype for casin 81 〉;〈Prototype for cacos 83 〉;〈Prototype for catan 85 〉;〈Prototype for csinh 90 〉;〈Prototype for ccosh 88 〉;〈Prototype for ctanh 92 〉;〈Prototype for catanh 94 〉;〈Prototype for casinh 96 〉;〈Prototype for cexp 99 〉;〈Prototype for clog 101 〉;〈Prototype for clog10 103 〉;〈Prototype for new carray 106 〉;〈Prototype for free carray 108 〉;〈Prototype for copy carray 110 〉;〈Prototype for set carray 112 〉;

Page 14: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

14 Mie Scattering (Version 1.0): BASIC ROUTINES

33. Basic routines.

34. A simple error routine.〈Prototype for complex error 34 〉 ≡

static void complex error (char ∗s)This code is used in section 35.

35. 〈Definition for complex error 35 〉 ≡〈Prototype for complex error 34 〉{

printf ("%s\n", s);exit (1);

}This code is used in section 31.

36. This is shorthand for setting a complex number. It just returns a complex equal to a+ bi

〈Prototype for cset 36 〉 ≡struct complex cset (double a,double b)

This code is used in sections 32 and 37.

37. 〈Definition for cset 37 〉 ≡〈Prototype for cset 36 〉{

struct complex c;

c.re = a;c.im = b;return c;

}This code is used in section 31.

38. A variation on cset in which the complex number is specifed using polar coordinates.〈Prototype for cpolarset 38 〉 ≡

struct complex cpolarset (double r,double theta )

This code is used in sections 32 and 39.

cabs : double, §40.cacos : struct complex, §83.cadd : struct complex, §55.carg : double, §44.casin : struct complex, §81.casinh : struct complex, §96.catan : struct complex, §85.catanh : struct complex, §94.ccos : struct complex, §77.ccosh : struct complex, §88.cdiv : struct complex, §61.cexp : struct complex, §99.cinv : struct complex, §52.

clog : struct complex, §101.clog10 : struct complex, §103.cmul : struct complex, §59.cnorm : double, §46.conj : struct complex, §42.copy carray : struct complex ∗,§110.

crdiv : double, §63.crmul : double, §65.csadd : struct complex, §70.csdiv : struct complex, §72.csin : struct complex, §75.csinh : struct complex, §90.

csmul : struct complex, §68.csqr : struct complex, §50.csqrt : struct complex, §48.csub : struct complex, §57.ctan : struct complex, §79.ctanh : struct complex, §92.exit , <stdlib.h>.free carray : void, §108.new carray : struct complex ∗,§106.

printf , <stdio.h>.set carray : void, §112.

Page 15: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): BASIC ROUTINES 15

39. 〈Definition for cpolarset 39 〉 ≡〈Prototype for cpolarset 38 〉{

return cset (r ∗ cos (theta ), r ∗ sin (theta ));}

This code is used in section 31.

40. This routine returns the absolute value of a complex number√zz∗. To avoid unnecessary

loss of accuracy as explained in §5.4 of Numerical Recipes in C

〈Prototype for cabs 40 〉 ≡double cabs (struct complex z)

This code is used in sections 32 and 41.

41. 〈Definition for cabs 41 〉 ≡〈Prototype for cabs 40 〉{

double x, y, temp ;

x = fabs (z.re );y = fabs (z.im );if (x ≡ 0.0) return y;if (y ≡ 0.0) return x;if (x > y) {

temp = y/x;return (x ∗ sqrt (1.0 + temp ∗ temp));

}temp = x/y;return (y ∗ sqrt (1.0 + temp ∗ temp));

}This code is used in section 31.

42. Returns the conjugate of the complex number z

〈Prototype for conj 42 〉 ≡struct complex conj (struct complex z)

This code is used in sections 32 and 43.

43. 〈Definition for conj 43 〉 ≡〈Prototype for conj 42 〉{

return cset (z.re ,−z.im );}

This code is used in section 31.

44. 〈Prototype for carg 44 〉 ≡double carg (struct complex z)

This code is used in sections 32 and 45.

Page 16: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

16 Mie Scattering (Version 1.0): BASIC ROUTINES

45. 〈Definition for carg 45 〉 ≡〈Prototype for carg 44 〉{

return atan2 (z.im , z.re );}

This code is used in section 31.

46. Returns the square of the modulus of the complex number zz∗

〈Prototype for cnorm 46 〉 ≡double cnorm (struct complex z)

This code is used in sections 32 and 47.

47. 〈Definition for cnorm 47 〉 ≡〈Prototype for cnorm 46 〉{

return (z.re ∗ z.re + z.im ∗ z.im );}

This code is used in section 31.

48. 〈Prototype for csqrt 48 〉 ≡struct complex csqrt (struct complex z)

This code is used in sections 32 and 49.

49. 〈Definition for csqrt 49 〉 ≡〈Prototype for csqrt 48 〉{

double a, b;

if ((z.re ≡ 0.0) ∧ (z.im ≡ 0.0)) return cset (0, 0);a = sqrt ((fabs (z.re ) + cabs (z)) ∗ 0.5);if (z.re ≥ 0) b = z.im/(a+ a);else {b = z.im < 0 ? −a : a;a = z.im/(b+ b);

}return cset (a, b);

}This code is used in section 31.

50. Returns the product of a complex number with itself z · z. If you want z · z∗ then usecnorm .〈Prototype for csqr 50 〉 ≡

struct complex csqr (struct complex z)

This code is used in sections 32 and 51.

atan2 , <math.h>.complex: struct, §32.cos , <math.h>.cpolarset : struct complex, §38.

cset : struct complex, §36.fabs , <math.h>.im : double, §32.r: double, §38.

re : double, §32.sin , <math.h>.sqrt , <math.h>.theta : double, §38.

Page 17: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): BASIC ROUTINES 17

51. 〈Definition for csqr 51 〉 ≡〈Prototype for csqr 50 〉{

return cmul (z, z);}

This code is used in section 31.

52. Returns the reciprocal of z.〈Prototype for cinv 52 〉 ≡

struct complex cinv (struct complex w)

This code is used in sections 32 and 53.

53. 〈Definition for cinv 53 〉 ≡〈Prototype for cinv 52 〉{

double r, d;

if ((w.re ≡ 0) ∧ (w.im ≡ 0)) complex error ("Attempt to invert 0+0i");if (fabs (w.re ) ≥ fabs (w.im )) {r = w.im/w.re ;d = 1/(w.re + r ∗ w.im );return cset (d,−r ∗ d);

}r = w.re/w.im ;d = 1/(w.im + r ∗ w.re );return cset (r ∗ d,−d);

}This code is used in section 31.

Page 18: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

18 Mie Scattering (Version 1.0): TWO COMPLEX NUMBERS

54. Two complex numbers.

55. Returns the sum of the two complex numbers a and b

〈Prototype for cadd 55 〉 ≡struct complex cadd (struct complex z, struct complex w)

This code is used in sections 32 and 56.

56. 〈Definition for cadd 56 〉 ≡〈Prototype for cadd 55 〉{

struct complex c;

c.im = z.im + w.im ;c.re = z.re + w.re ;return c;

}This code is used in section 31.

57. Returns the difference of two complex numbers z − w〈Prototype for csub 57 〉 ≡

struct complex csub(struct complex z, struct complex w)

This code is used in sections 32 and 58.

58. 〈Definition for csub 58 〉 ≡〈Prototype for csub 57 〉{

struct complex c;

c.im = z.im − w.im ;c.re = z.re − w.re ;return c;

}This code is used in section 31.

59. Returns the product of two complex numbers z · w〈Prototype for cmul 59 〉 ≡

struct complex cmul (struct complex z, struct complex w)

This code is used in sections 32 and 60.

a: double, §49.b: double, §49.complex: struct, §32.complex error : static void, §34.

cset : struct complex, §36.csqr : struct complex, §50.fabs , <math.h>.

im : double, §32.re : double, §32.z: struct complex, §50.

Page 19: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): TWO COMPLEX NUMBERS 19

60. 〈Definition for cmul 60 〉 ≡〈Prototype for cmul 59 〉{

struct complex c;

c.re = z.re ∗ w.re − z.im ∗ w.im ;c.im = z.im ∗ w.re + z.re ∗ w.im ;return c;

}This code is used in section 31.

61. Returns the quotient of two complex numbers z/w see §5.4 of Numerical Recipes in C〈Prototype for cdiv 61 〉 ≡

struct complex cdiv (struct complex z, struct complex w)

This code is used in sections 32 and 62.

62. 〈Definition for cdiv 62 〉 ≡〈Prototype for cdiv 61 〉{

struct complex c;double r, denom ;

if ((w.re ≡ 0) ∧ (w.im ≡ 0)) complex error ("Attempt to divide by 0+0i");if (fabs (w.re ) ≥ fabs (w.im )) {r = w.im/w.re ;denom = w.re + r ∗ w.im ;c.re = (z.re + r ∗ z.im )/denom ;c.im = (z.im − r ∗ z.re )/denom ;

}else {r = w.re/w.im ;denom = w.im + r ∗ w.re ;c.re = (z.re ∗ r + z.im )/denom ;c.im = (z.im ∗ r − z.re )/denom ;

}return c;

}This code is used in section 31.

63. Returns the real part of the quotient of two complex numbers Re(z/w). Note how this isa special case of cdiv above〈Prototype for crdiv 63 〉 ≡

double crdiv (struct complex z, struct complex w)

This code is used in sections 32 and 64.

64. 〈Definition for crdiv 64 〉 ≡〈Prototype for crdiv 63 〉{

double r, c, denom ;

if ((w.re ≡ 0) ∧ (w.im ≡ 0)) complex error ("Attempt to find real part with divisor 0+0i");

Page 20: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

20 Mie Scattering (Version 1.0): TWO COMPLEX NUMBERS

if (fabs (w.re ) ≥ fabs (w.im )) {r = w.im/w.re ;denom = w.re + r ∗ w.im ;c = (z.re + r ∗ z.im )/denom ;

}else {r = w.re/w.im ;denom = w.im + r ∗ w.re ;c = (z.re ∗ r + z.im )/denom ;

}return c;

}This code is used in section 31.

65. Returns the real part of the product of two complex numbers Re(z · w)〈Prototype for crmul 65 〉 ≡

double crmul (struct complex z, struct complex w)

This code is used in sections 32 and 66.

66. 〈Definition for crmul 66 〉 ≡〈Prototype for crmul 65 〉{

return z.re ∗ w.re − z.im ∗ w.im ;}

This code is used in section 31.

cmul : struct complex, §59.complex: struct, §32.complex error : static void, §34.

fabs , <math.h>.im : double, §32.re : double, §32.

w: struct complex, §59.z: struct complex, §59.

Page 21: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): A SCALAR AND A COMPLEX NUMBER 21

67. A scalar and a complex number.

68. Returns the product of a scalar with a complex number〈Prototype for csmul 68 〉 ≡

struct complex csmul (double x, struct complex z)

This code is used in sections 32 and 69.

69. 〈Definition for csmul 69 〉 ≡〈Prototype for csmul 68 〉{

struct complex c;

c.re = z.re ∗ x;c.im = z.im ∗ x;return c;

}This code is used in section 31.

70. Returns the sum of a scalar and a complex number〈Prototype for csadd 70 〉 ≡

struct complex csadd (double x, struct complex z)

This code is used in sections 32 and 71.

71. 〈Definition for csadd 71 〉 ≡〈Prototype for csadd 70 〉{

struct complex c;

c.re = x+ z.re ;c.im = z.im ;return c;

}This code is used in section 31.

72. Returns the quotient of real number by a complex number z. Again a special case of cdiv〈Prototype for csdiv 72 〉 ≡

struct complex csdiv (double x, struct complex w)

This code is used in sections 32 and 73.

73. 〈Definition for csdiv 73 〉 ≡〈Prototype for csdiv 72 〉{

struct complex c;double r, factor ;

if ((w.re ≡ 0) ∧ (w.im ≡ 0)) complex error ("Attempt to divide scalar by 0+0i");if (fabs (w.re ) ≥ fabs (w.im )) {r = w.im/w.re ;factor = x/(w.re + r ∗ w.im );c.re = factor ;c.im = −r ∗ factor ;

Page 22: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

22 Mie Scattering (Version 1.0): A SCALAR AND A COMPLEX NUMBER

}else {r = w.re/w.im ;factor = x/(w.im + r ∗ w.re );c.im = −factor ;c.re = r ∗ factor ;

}return c;

}This code is used in section 31.

cdiv : struct complex, §61.complex: struct, §32.

complex error : static void, §34.fabs , <math.h>.

im : double, §32.re : double, §32.

Page 23: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): TRIGONOMETRIC FUNCTIONS 23

74. Trigonometric Functions.

75. The complex sine.〈Prototype for csin 75 〉 ≡

struct complex csin (struct complex z)

This code is used in sections 32 and 76.

76. 〈Definition for csin 76 〉 ≡〈Prototype for csin 75 〉{

return cset (sin (z.re ) ∗ cosh (z.im ), cos (z.re ) ∗ sinh (z.im ));}

This code is used in section 31.

77. The complex cosine.〈Prototype for ccos 77 〉 ≡

struct complex ccos (struct complex z)

This code is used in sections 32 and 78.

78. 〈Definition for ccos 78 〉 ≡〈Prototype for ccos 77 〉{

return cset (cos (z.re ) ∗ cosh (z.im ),−(sin (z.re ) ∗ sinh (z.im )));}

This code is used in section 31.

79. The complex tangent.

tan(a+ bi) =sin 2a+ i sinh 2bcos 2a+ cosh 2b

or

tan(a+ bi) =2 sin 2a+ i exp(2b)− i exp(−2b)2 cos 2a+ exp(2b) + exp(−2b)

it is easy to see that if 2b is large, then problems arise.The number DBL_MAX_10_EXP is the value c such that 10c can be represented by a double

precision variable. Now we are interested in the maximum exponential, one would just multiplyc by ln 10 = 2.3 to get such an exponential. This could then be compared against the value of2b to figure out when an approximation should be used. Slightly more conservatively, one couldjust test to see when

2b > 2c

and adjust accordingly.〈Prototype for ctan 79 〉 ≡

struct complex ctan (struct complex z)

This code is used in sections 32 and 80.

Page 24: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

24 Mie Scattering (Version 1.0): TRIGONOMETRIC FUNCTIONS

80. 〈Definition for ctan 80 〉 ≡〈Prototype for ctan 79 〉{

double t, x, y;

if (z.im ≡ 0) return cset (tan (z.re ), 0.0);if (z.im > DBL_MAX_10_EXP) return cset (0.0, 1.0);if (z.im < −DBL_MAX_10_EXP) return cset (0.0,−1.0);x = 2 ∗ z.re ;y = 2 ∗ z.im ;t = cos (x) + cosh (y);if (t ≡ 0) complex error ("Complex tangent is infinite");return cset (sin (x)/t, sinh (y)/t);

}This code is used in section 31.

81. The complex inverse sine.〈Prototype for casin 81 〉 ≡

struct complex casin (struct complex z)

This code is used in sections 32 and 82.

82. 〈Definition for casin 82 〉 ≡〈Prototype for casin 81 〉{

struct complex x;

x = clog (cadd (cset (−z.im , z.re ), csqrt (csub(cset (1, 0), cmul (z, z)))));return cset (x.im ,−x.re );

}This code is used in section 31.

83. The complex inverse cosine〈Prototype for cacos 83 〉 ≡

struct complex cacos (struct complex z)

This code is used in sections 32 and 84.

84. 〈Definition for cacos 84 〉 ≡〈Prototype for cacos 83 〉{

struct complex x;

x = clog (cadd (z, cmul (cset (0, 1), csqrt (csub(cset (1, 0), csqr (z))))));return cset (x.im ,−x.re );

}This code is used in section 31.

cadd : struct complex, §55.clog : struct complex, §101.cmul : struct complex, §59.complex: struct, §32.complex error : static void, §34.cos , <math.h>.

cosh , <math.h>.cset : struct complex, §36.csqr : struct complex, §50.csqrt : struct complex, §48.csub : struct complex, §57.DBL_MAX_10_EXP, <float.h>.

im : double, §32.re : double, §32.sin , <math.h>.sinh , <math.h>.tan , <math.h>.

Page 25: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): TRIGONOMETRIC FUNCTIONS 25

85. The complex inverse tangent〈Prototype for catan 85 〉 ≡

struct complex catan (struct complex z)

This code is used in sections 32 and 86.

86. 〈Definition for catan 86 〉 ≡〈Prototype for catan 85 〉{

struct complex x;

x = clog (cdiv (cset (z.re , 1 + z.im ), cset (−z.re , 1− z.im )));return cset (−x.im/2, x.re/2);

}This code is used in section 31.

Page 26: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

26 Mie Scattering (Version 1.0): HYPERBOLIC FUNCTIONS

87. Hyperbolic functions.

88. 〈Prototype for ccosh 88 〉 ≡struct complex ccosh (struct complex z)

This code is used in sections 32 and 89.

89. 〈Definition for ccosh 89 〉 ≡〈Prototype for ccosh 88 〉{

return cset (cosh (z.re ) ∗ cos (z.im ), sinh (z.re ) ∗ sin (z.im ));}

This code is used in section 31.

90. 〈Prototype for csinh 90 〉 ≡struct complex csinh (struct complex z)

This code is used in sections 32 and 91.

91. 〈Definition for csinh 91 〉 ≡〈Prototype for csinh 90 〉{

return cset (sinh (z.re ) ∗ cos (z.im ), cosh (z.re ) ∗ sin (z.im ));}

This code is used in section 31.

92. 〈Prototype for ctanh 92 〉 ≡struct complex ctanh (struct complex z)

This code is used in sections 32 and 93.

93. 〈Definition for ctanh 93 〉 ≡〈Prototype for ctanh 92 〉{

double x = 2 ∗ z.re ;double y = 2 ∗ z.im ;double t = 1.0/(cosh (x) + cos (y));

return cset (t ∗ sinh (x), t ∗ sin (y));}

This code is used in section 31.

94. 〈Prototype for catanh 94 〉 ≡struct complex catanh (struct complex z)

This code is used in sections 32 and 95.

cdiv : struct complex, §61.clog : struct complex, §101.complex: struct, §32.cos , <math.h>.

cosh , <math.h>.cset : struct complex, §36.im : double, §32.

re : double, §32.sin , <math.h>.sinh , <math.h>.

Page 27: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): HYPERBOLIC FUNCTIONS 27

95. 〈Definition for catanh 95 〉 ≡〈Prototype for catanh 94 〉{

return catan (cset (−z.im , z.re ));}

This code is used in section 31.

96. 〈Prototype for casinh 96 〉 ≡struct complex casinh (struct complex z)

This code is used in sections 32 and 97.

97. 〈Definition for casinh 97 〉 ≡〈Prototype for casinh 96 〉{

return casin (cset (−z.im , z.re ));}

This code is used in section 31.

Page 28: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

28 Mie Scattering (Version 1.0): EXPONENTIALS AND LOGARITHMS

98. Exponentials and logarithms.

99. 〈Prototype for cexp 99 〉 ≡struct complex cexp(struct complex z)

This code is used in sections 32 and 100.

100. 〈Definition for cexp 100 〉 ≡〈Prototype for cexp 99 〉{

double x = exp(z.re );

return cset (x ∗ cos (z.im ), x ∗ sin (z.im ));}

This code is used in section 31.

101. 〈Prototype for clog 101 〉 ≡struct complex clog (struct complex z)

This code is used in sections 32 and 102.

102. 〈Definition for clog 102 〉 ≡〈Prototype for clog 101 〉{

return cset (log (cabs (z)), carg (z));}

This code is used in section 31.

103. 〈Prototype for clog10 103 〉 ≡struct complex clog10 (struct complex z)

This code is used in sections 32 and 104.

104. 〈Definition for clog10 104 〉 ≡〈Prototype for clog10 103 〉{

return cset (0.2171472409516259 ∗ log (cnorm (z)), carg (z));}

This code is used in section 31.

cabs : double, §40.carg : double, §44.casin : struct complex, §81.catan : struct complex, §85.catanh : struct complex, §94.

cnorm : double, §46.complex: struct, §32.cos , <math.h>.cset : struct complex, §36.exp , <math.h>.

im : double, §32.log , <math.h>.re : double, §32.sin , <math.h>.z: struct complex, §94.

Page 29: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): ARRAYS OF COMPLEX NUMBERS 29

105. Arrays of complex numbers.This assumes zero based arrays.

106. 〈Prototype for new carray 106 〉 ≡struct complex ∗new carray (long size )

This code is used in sections 32 and 107.

107. 〈Definition for new carray 107 〉 ≡〈Prototype for new carray 106 〉{

struct complex ∗a;

if (size ≤ 0) complex error ("Non−positive complex array size chosen");a = (struct complex ∗) malloc(size ∗ sizeof (struct complex));if (a ≡ Λ) complex error ("Can’t allocate complex array");return a;

}This code is used in section 31.

108. 〈Prototype for free carray 108 〉 ≡void free carray (struct complex ∗a)

This code is used in sections 32 and 109.

109. 〈Definition for free carray 109 〉 ≡〈Prototype for free carray 108 〉{

if (a 6= Λ) free (a);}

This code is used in section 31.

110. This allocates a new complex array and copies the contents of a into it.〈Prototype for copy carray 110 〉 ≡

struct complex ∗copy carray (struct complex ∗a, long size )

This code is used in sections 32 and 111.

111. 〈Definition for copy carray 111 〉 ≡〈Prototype for copy carray 110 〉{

struct complex ∗b = Λ;

if (a ≡ Λ) complex error ("Can’t duplicate a NULL complex array");b = new carray (size );if (b 6= Λ) memcpy (b, a, size ∗ sizeof (struct complex));return b;

}This code is used in section 31.

112. This puts z in all the entries in a complex array.〈Prototype for set carray 112 〉 ≡

void set carray (struct complex ∗a, long size , struct complex z)

This code is used in sections 32 and 113.

Page 30: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

30 Mie Scattering (Version 1.0): ARRAYS OF COMPLEX NUMBERS

113. 〈Definition for set carray 113 〉 ≡〈Prototype for set carray 112 〉{

long j;

if (a ≡ Λ) complex error ("Can’t operate on a NULL complex array");for (j = 0; j < size ; j++) a[j] = z;

}This code is used in section 31.

complex: struct, §32.complex error : static void, §34.

free : ???, §0.malloc : ???, §0.

memcpy , <string.h>.

Page 31: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): MIE SCATTERING ALGORITHMS 31

114. Mie Scattering Algorithms.This is a Mie scattering implementation. Several resources were used in creating this program.

First, the Fortran listing in Bohren and Huffman’s book was used. This listing was translatedinto Pascal and refined using various suggestions by Wiscombe. This version was used for acouple of years and later translated by me into C and then into CWeb with the documentationyou see here.

Finally, consider using ez Mie for problems that involve non-absorbing spheres and you don’tcare about the scattering phase function.

A short to do list includes• use Wiscombe’s trick to find the scattering functions• add code to deal with near zero entries in the Lentz routine• allow calculation of extinction efficiencies with zero angles.

115. There are seven basic functions that are defined.〈 mie.c 115 〉 ≡#include <math.h>

#include <stddef.h>

#include <stdio.h>

#include <stdlib.h>

#include "array.h"

#include "complex.h"

#include "mie.h"

〈Definition for mie error 118 〉〈Definition for Lentz Dn 123 〉〈Definition for Dn down 132 〉〈Definition for Dn up 129 〉〈Definition for small Mie 135 〉〈Definition for Mie 144 〉〈Definition for ez Mie 160 〉

116. Only the main function Mie is available for calling.〈 mie.h 116 〉 ≡〈Prototype for Lentz Dn 122 〉;〈Prototype for Dn down 131 〉;〈Prototype for Dn up 128 〉;〈Prototype for small Mie 134 〉;〈Prototype for Mie 143 〉;〈Prototype for ez Mie 159 〉;

117. A simple error routine that is not used elsewhere.〈Prototype for mie error 117 〉 ≡

static void mie error (char ∗s)This code is used in section 118.

118. 〈Definition for mie error 118 〉 ≡〈Prototype for mie error 117 〉{

printf ("Mie −− %s\n", s);

Page 32: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

32 Mie Scattering (Version 1.0): MIE SCATTERING ALGORITHMS

exit (1);}

This code is used in section 115.

Dn down : void, §131.Dn up : void, §128.exit , <stdlib.h>.

ez Mie : void, §159.Lentz Dn : struct complex, §122.Mie : void, §143.

printf , <stdio.h>.small Mie : void, §134.

Page 33: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): THE LOGARITHMIC DERIVATIVE DN 33

119. The logarithmic derivative Dn.

120. This routine uses a continued fraction method to compute Dn(z) proposed by Lentz.*This method eliminates many weaknesses in previous algorithms using forward recursion.

I should add code to deal with αj,1 ≈ 0.The logarithmic derivative Dn is defined as

Dn = −nz

+Jn−1/2(z)Jn+1/2(z)

Equation (5) in Lentz’s paper can be used to obtain

Jn−1/2(z)Jn+1/2(z)

=2n+ 1z

+1

−2n+ 3z

+1

2n+ 5z

+1

−2n+ 7z

+ · · ·

Now ifαi,j = [ai, ai−1, . . . , aj ] = ai +

1

ai−1 +1

ai−2 + · · ·1aj

we seek to createα = α1,1 α2,1 · · ·αj,1 β = α2,2 α3,2 · · ·αj,2

since Lentz showed thatJn−1/2(z)Jn+1/2(z)

≈ α

β

121. The whole goal is to iterate until the α and β are identical to the number of digits desired.Once this is achieved, then use equations this equation and the first equation for the logarithmicderivative to calculate Dn(z).

122. 〈Prototype for Lentz Dn 122 〉 ≡struct complex Lentz Dn (struct complex z, long n)

This code is used in sections 116 and 123.

123. 〈Definition for Lentz Dn 123 〉 ≡〈Prototype for Lentz Dn 122 〉{

struct complex alpha j1 , alpha j2 , zinv , aj ;struct complex alpha , result , ratio , runratio ;

〈Calculate first alpha and beta 124 〉do 〈Calculate next ratio 125 〉 while (fabs (cabs (ratio)− 1.0) > 1 · 10−12);result = cadd (csdiv (−n, z), runratio);return result ;

}This code is used in section 115.

Page 34: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

34 Mie Scattering (Version 1.0): THE LOGARITHMIC DERIVATIVE DN

124. Here I initialize for looping. Of course it is kind of tricky, but what else would you expect.The value of aj is given by,

aj = (−1)j+1 2n+ 2j − 1z

The first terms for α and beta are

α = a1

(a2 +

1a1

)β = a2

〈Calculate first alpha and beta 124 〉 ≡zinv = csdiv (2.0, z);alpha = csmul (n+ 0.5, zinv );aj = csmul (−n− 1.5, zinv );alpha j1 = cadd (aj , cinv (alpha ));alpha j2 = aj ;ratio = cdiv (alpha j1 , alpha j2 );runratio = cmul (alpha , ratio);

This code is used in section 123.

beta : double, §145.cabs : double, §40.cadd : struct complex, §55.cdiv : struct complex, §61.

cinv : struct complex, §52.cmul : struct complex, §59.complex: struct, §32.

csdiv : struct complex, §72.csmul : struct complex, §68.fabs , <math.h>.

Page 35: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): THE LOGARITHMIC DERIVATIVE DN 35

125. To calculate the next α and β, I use

aj+1 = −aj + (−1)j2z

to find the next aj and

αj+1 = aj +1αj, and βj+1 = aj +

1βj

and〈Calculate next ratio 125 〉 ≡{

aj .re = zinv .re − aj .re ;aj .im = zinv .im − aj .im ;alpha j1 = cadd (cinv (alpha j1 ), aj );alpha j2 = cadd (cinv (alpha j2 ), aj );ratio = cdiv (alpha j1 , alpha j2 );zinv .re ∗= −1;zinv .im ∗= −1;runratio = cmul (ratio , runratio);

}This code is used in section 123.

Page 36: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

36 Mie Scattering (Version 1.0): DN BY UPWARD RECURRENCE

126. Dn by upward recurrence.Calculating the logarithmic derivative Dn(ρ) using the upward recurrence relation,

Dn(z) =1

n/z −Dn−1(z)− n

z

127. To calculate the initial value we must figure out D0(z). This is

D0(z) =d

dzlnψ0(z) =

d

dzln sin(z) =

cos zsin z

The only tricky part is finding the tangent of a complex number, but this is all stuck in complex.w.Finally, note that the returned array ∗D is set-up so that Dn(z) =D[n]. Therefore the first

value for D1(z) will be found not in D[0], but rather in D[1].

128. 〈Prototype for Dn up 128 〉 ≡void Dn up(struct complex z, long nstop , struct complex ∗D)

This code is used in sections 116 and 129.

129. 〈Definition for Dn up 129 〉 ≡〈Prototype for Dn up 128 〉{

struct complex zinv , k over z ;long k;

D[0] = cinv (ctan (z));zinv = cinv (z);for (k = 1; k < nstop ; k++) {

k over z = csmul (k, zinv );D[k] = csub(cinv (csub(k over z , D[k − 1])), k over z );

}}

This code is used in section 115.

aj : struct complex, §123.alpha j1 : struct complex, §123.alpha j2 : struct complex, §123.cadd : struct complex, §55.cdiv : struct complex, §61.cinv : struct complex, §52.

cmul : struct complex, §59.complex: struct, §32.csmul : struct complex, §68.csub : struct complex, §57.ctan : struct complex, §79.D: struct complex ∗, §145.

im : double, §32.n: long, §122.ratio : struct complex, §123.re : double, §32.runratio : struct complex, §123.zinv : struct complex, §123.

Page 37: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): DN BY DOWNWARDS RECURRENCE 37

130. Dn by downwards recurrence.Start downwards recurrence using Lentz method, then find earlier terms of the logarithmic

derivative Dn(z) using the recurrence relation,

Dn−1(z) =n

z− 1Dn(z) + n/z

This is a pretty straightforward procedure.Finally, note that the returned array ∗D is set-up so that Dn(z) =D[n]. Therefore the first

value for D1(z) will be found not in D[0], but rather in D[1].

131. 〈Prototype for Dn down 131 〉 ≡void Dn down (struct complex z, long nstop , struct complex ∗D)

This code is used in sections 116 and 132.

132. 〈Definition for Dn down 132 〉 ≡〈Prototype for Dn down 131 〉{

long k;struct complex zinv , k over z ;

D[nstop − 1] = Lentz Dn (z,nstop);zinv = cinv (z);for (k = nstop − 1; k ≥ 1; k−−) {

k over z = csmul (k, zinv );D[k − 1] = csub(k over z , cinv (cadd (D[k], k over z )));

}}

This code is used in section 115.

Page 38: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

38 Mie Scattering (Version 1.0): SMALL SPHERES

133. Small Spheres.This calculates everything accurately for small spheres. This approximation is necessary

because in the small particle or Rayleigh limit x → 0 the Mie formulas become ill-conditioned.The method was taken from Wiscombe’s paper and has been tested for several complex indicesof refraction. Wiscombe uses this when

x|m| ≤ 0.1

and says this routine should be accurate to six places.If nangles ≡ 0 or s1 ≡ Λ or s2 ≡ Λ then this routine will do the right thing—it will calculate

the efficiencies and the anisotropy, but will not calculate any of the scattering amplitudes.

134. 〈Prototype for small Mie 134 〉 ≡void small Mie (double x, struct complex m,double ∗mu , long nangles , struct complex

∗s1 , struct complex ∗s2 ,double ∗qext ,double ∗qsca ,double ∗qback ,double ∗g)

This code is used in sections 116 and 135.

135. 〈Definition for small Mie 135 〉 ≡〈Prototype for small Mie 134 〉{

struct complex ahat1 , ahat2 , bhat1 ;struct complex z0 , m2 , m4 ;double x2 , x3 , x4 ;

if ((s1 ≡ Λ) ∨ (s2 ≡ Λ)) nangles = 0;m2 = csqr (m);m4 = csqr (m2 );x2 = x ∗ x;x3 = x2 ∗ x;x4 = x2 ∗ x2 ;z0 .re = −m2 .im ;z0 .im = m2 .re − 1;〈Calculate a1 136 〉〈Calculate b1 137 〉〈Calculate a2 138 〉〈Calculate small Mie efficiencies and asymmetry 140 〉〈Calculate small Mie scattering amplitudes 141 〉

}This code is used in section 115.

cadd : struct complex, §55.cinv : struct complex, §52.complex: struct, §32.csmul : struct complex, §68.csqr : struct complex, §50.

csub : struct complex, §57.D: struct complex ∗, §128.im : double, §32.Lentz Dn : struct complex, §122.n: long, §122.

nangles : long, §165.re : double, §32.s1 : struct complex ∗, §165.s2 : struct complex ∗, §165.

Page 39: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): SMALL SPHERES 39

136. The formula for a1 is

a1 = 2im2 − 1

3

1− 0.1x2 + 4m2 + 51400 x4

D

where

D = m2 + 2 + (1− 0.7m2)x2 − 8m4 − 385m2 + 3501400

x4 + 2im2 − 1

3x3(1− 0.1x2)

〈Calculate a1 136 〉 ≡{

struct complex z1 , z2 , z3 , z4 , D;

if (m.re ≡ 0) {z3 = cset (0.0, 2.0/3.0 ∗ (1.0− 0.2 ∗ x2 ));D = cset (1.0− 0.5 ∗ x2 , 2.0/3.0 ∗ x3 );

}else {

z1 = csmul (2.0/3.0, z0 );z2 .re = 1.0− 0.1 ∗ x2 + (4.0 ∗m2 .re + 5.0) ∗ x4 /1400.0;z2 .im = 4.0 ∗ x4 ∗m2 .im/1400.0;z3 = cmul (z1 , z2 );z4 = csmul (x3 ∗ (1.0− 0.1 ∗ x2 ), z1 );D.re = 2.0 + m2 .re + (1− 0.7 ∗m2 .re ) ∗ x2 + (8 ∗m4 .re − 385 ∗m2 .re + 350.0)/1400 ∗ x4 + z4 .re ;D.im = (−0.7 ∗m2 .im ) ∗ x2 + (8 ∗m4 .im − 385 ∗m2 .im )/1400 ∗ x4 + z4 .im ;

}ahat1 = cdiv (z3 , D);

}This code is used in section 135.

137. The formula for b1 is

b1 = ix2m2 − 145

1 + 2m2 − 570 x2

1− 2m2 − 530 x2

〈Calculate b1 137 〉 ≡{

struct complex z2 , z6 , z7 ;

if (m.re ≡ 0) {bhat1 = cdiv (cset (0.0,−(1.0− 0.1 ∗ x2 )/3.0), cset (1 + 0.5 ∗ x2 ,−x3 /3));

}else {

z2 = csmul (x2 /45, z0 );z6 .re = 1.0 + (2.0 ∗m2 .re − 5.0) ∗ x2 /70.0;z6 .im = m2 .im ∗ x2 /35;

Page 40: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

40 Mie Scattering (Version 1.0): SMALL SPHERES

z7 .re = 1.0− (2.0 ∗m2 .re − 5.0) ∗ x2 /30.0;z7 .im = −m2 .im ∗ x2 /15;bhat1 = cmul (z2 , cdiv (z6 , z7 ));

}}

This code is used in section 135.

138. The formula for a2 is

a2 = ix2m2 − 115

1− 114x

2

2m2 + 3− 2m2 − 714 x2

〈Calculate a2 138 〉 ≡{

struct complex z3 , z8 ;

if (m.re ≡ 0) {ahat2 = cset (0, x2 /30.);

}else {

z3 = csmul ((1.0− x2 /14) ∗ x2 /15.0, z0 );z8 .re = 2.0 ∗m2 .re + 3.0− (m2 .re/7.0− 0.5) ∗ x2 ;z8 .im = 2.0 ∗m2 .im −m2 .im/7.0 ∗ x2 ;ahat2 = cdiv (z3 , z8 );

}}

This code is used in section 135.

ahat1 : struct complex, §135.ahat2 : struct complex, §135.bhat1 : struct complex, §135.cdiv : struct complex, §61.cmul : struct complex, §59.complex: struct, §32.

cset : struct complex, §36.csmul : struct complex, §68.im : double, §32.m: struct complex, §134.m2 : struct complex, §135.m4 : struct complex, §135.

re : double, §32.x2 : double, §135.x3 : double, §135.x4 : double, §135.z0 : struct complex, §135.

Page 41: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): SMALL SPHERES 41

139. The scattering and extinction efficiencies are given by

Qext = 6xRe[a1 + b1 +

53a2

]Qsca = 6xT

g =1T

Re[a1(a2 + b1)∗

]T = |a1|2 + |b1|2 +

53|a2|2

I also calculate the backscattering efficiency so that it will be calculated correctly even whennangles ≡ 0. The backscattering efficiency Qback is defined as

Qback =σback

πa2=|S1(−1)|2

x2

where σback is the backscattering cross section. The expression for S1(µ) given in the chunkbelow yields

S1(−1)x

=32x2

[a1 − b1 −

53a2

]This only remains to be squared before the efficiency for backscattering is obtained.

140. 〈Calculate small Mie efficiencies and asymmetry 140 〉 ≡{

struct complex ss1 ;double T ;

T = cnorm (ahat1 ) + cnorm (bhat1 ) + (5/3) ∗ cnorm (ahat2 );∗qsca = 6 ∗ x4 ∗ T ;∗qext = 6 ∗ x ∗ (ahat1 .re + bhat1 .re + (5/3) ∗ ahat2 .re );∗g = (ahat1 .re ∗ (ahat2 .re + bhat1 .re ) + ahat1 .im ∗ (ahat2 .im + bhat1 .im ))/T ;ss1 .re = 1.5 ∗ x2 ∗ (ahat1 .re − bhat1 .re − (5/3) ∗ ahat2 .re );ss1 .re = 1.5 ∗ x2 ∗ (ahat1 .im − bhat1 .im − (5/3) ∗ ahat2 .im );∗qback = cnorm (ss1 );

}This code is used in section 135.

141. Here is where the scattering functions get calculated according to

S1(µ) =32x3

[a1 +

(b1 +

53a2

]S2(µ) =

32x3

[b1 + a1µ+

53a2(2µ2 − 1)

]Since this is the last thing to get calculated, I take the liberty of mucking around with thevariables a1, b1, a2, and x3

〈Calculate small Mie scattering amplitudes 141 〉 ≡{

double muj , angle ;

Page 42: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

42 Mie Scattering (Version 1.0): SMALL SPHERES

long j;

x3 ∗= 1.5;ahat1 .re ∗= x3 ;ahat1 .im ∗= x3 ;bhat1 .re ∗= x3 ;bhat1 .im ∗= x3 ;ahat2 .re ∗= x3 ∗ 5/3;ahat2 .im ∗= x3 ∗ 5/3;for (j = 0; j < nangles ; j++) {

muj = mu [j];angle = 2 ∗muj ∗muj − 1;s1 [j].re = ahat1 .re + (bhat1 .re + ahat2 .re ) ∗muj ;s1 [j].im = ahat1 .im + (bhat1 .im + ahat2 .im ) ∗muj ;s2 [j].re = bhat1 .re + ahat1 .re ∗muj + ahat2 .re ∗ angle ;s2 [j].im = bhat1 .im + ahat1 .im ∗muj + ahat2 .im ∗ angle ;

}}

This code is used in section 135.

ahat1 : struct complex, §135.ahat2 : struct complex, §135.bhat1 : struct complex, §135.cnorm : double, §46.complex: struct, §32.g: double ∗, §134.im : double, §32.

mu : double ∗, §134.nangles : long, §134.qback : double ∗, §134.qext : double ∗, §134.qsca : double ∗, §134.re : double, §32.

s1 : struct complex ∗, §134.s2 : struct complex ∗, §134.x: double, §134.x2 : double, §135.x3 : double, §135.x4 : double, §135.

Page 43: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): ARBITRARY SPHERES 43

142. Arbitrary Spheres.Calculates the amplitude scattering matrix elements and efficiencies for extinction, total scat-

tering and backscattering for a given size parameter and relative refractive index. The basicalgorithm follows Bohren and Huffman originally written in Fortran. The code was translatedinto CWeb and documented by Scott Prahl.

Many improvements suggested by Wiscombe have been incorporated. In particular, eitherupward or downward iteration will be used to calculate the lograthmic derivative Dn(z).

Routine preliminary checking suggests that everything is being calculated ok except g.Space must have been allocated for the scattering amplitude angles s1 and s2 before this

routine is called.

143. 〈Prototype for Mie 143 〉 ≡void Mie (double x, struct complex m,double ∗mu , long nangles , struct complex ∗s1 , struct

complex ∗s2 ,double ∗qext ,double ∗qsca ,double ∗qback ,double ∗g)

This code is used in sections 116 and 144.

144. 〈Definition for Mie 144 〉 ≡〈Prototype for Mie 143 〉{〈Declare variables for Mie 145 〉〈Catch bogus input values 146 〉〈Deal with small spheres 147 〉〈Calculate nstop 149 〉〈Mie allocate and initialize angle arrays 148 〉if (m.re > 0) 〈Calculate the logarithmic derivatives 150 〉〈Prepare to sum over all nstop terms 151 〉for (n = 1; n ≤ nstop ; n++) {〈Establish an and bn 152 〉〈Calculate phase function for each angle 153 〉〈 Increment cross sections 154 〉〈Prepare for the next iteration 155 〉

}〈Calculate Efficiencies 156 〉〈Free allocated memory 157 〉

}This code is used in section 115.

145. 〈Declare variables for Mie 145 〉 ≡struct complex ∗D;struct complex z1 , an , bn , bnm1 , anm1 , qbcalc ;double ∗pi0 , ∗pi1 , ∗tau ;struct complex xi , xi0 , xi1 ;double psi , psi0 , psi1 ;double alpha , beta , factor ;long n, k, nstop , sign ;

This code is used in section 144.

Page 44: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

44 Mie Scattering (Version 1.0): ARBITRARY SPHERES

146. 〈Catch bogus input values 146 〉 ≡if (m.im > 0.0) mie error ("This program requires m.im>=0");if (x ≤ 0.0) mie error ("This program requires positive sphere sizes");if (nangles < 0) mie error ("This program requires non−negative angle sizes");if (nangles < 0) mie error ("This program requires non−negative angle sizes");if ((nangles > 0) ∧ (s1 ≡ Λ)) mie error ("Space must be allocated for s1 if nangles!=0");if ((nangles > 0) ∧ (s2 ≡ Λ)) mie error ("Space must be allocated for s2if nangles!=0");if (x > 20000) mie error ("Program not validated for spheres with x>20000");

This code is used in section 144.

147. 〈Deal with small spheres 147 〉 ≡if (((m.re ≡ 0) ∧ (x < 0.1)) ∨ ((m.re > 0.0) ∧ (cabs (m) ∗ x < 0.1))) {

small Mie (x,m,mu ,nangles , s1 , s2 , qext , qsca , qback , g);return;

}This code is used in section 144.

148. 〈Mie allocate and initialize angle arrays 148 〉 ≡if (nangles > 0) {

set carray (s1 ,nangles , cset (0.0, 0.0));set carray (s2 ,nangles , cset (0.0, 0.0));pi0 = new darray (nangles );pi1 = new darray (nangles );tau = new darray (nangles );set darray (pi0 ,nangles , 0.0);set darray (tau ,nangles , 0.0);set darray (pi1 ,nangles , 1.0);

}This code is used in section 144.

149. Calculate number of terms to be summed in series after Wiscombe〈Calculate nstop 149 〉 ≡

nstop = floor (x+ 4.05 ∗ pow (x, 0.33333) + 2.0);

This code is used in section 144.

cabs : double, §40.complex: struct, §32.cset : struct complex, §36.floor , <math.h>.im : double, §32.mie error : static void, §117.

n: long, §122.new darray : double ∗, §8.nstop : long, §131.pow , <math.h>.re : double, §32.

s1 : struct complex ∗, §134.s2 : struct complex ∗, §134.set carray : void, §112.set darray : void, §14.small Mie : void, §134.

Page 45: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): ARBITRARY SPHERES 45

150. Allocate and initialize the space for the arrays. One noteworthy aspect is that the complexarray D is allocated from 0 to nstop . This allows D to be a one-based array from 1 to nstopinstead of a zero-based array from 0 to nstop − 1. Therefore D[n] will directly correspond to Dn

in Bohren. Furthermore, an and bn will correspond to an and bn. The angular arrays are stillzero-based.

Use formula 7 from Wiscombe’s paper to figure out if upwards or downwards recurrence shouldbe used. Namely if

mImx ≤ 13.78m2Re − 10.8mRe + 3.9

the upward recurrence would be stable.〈Calculate the logarithmic derivatives 150 〉 ≡{

struct complex z;

z = csmul (x,m);D = new carray (nstop + 1);if (D ≡ Λ) mie error ("Cannot allocate log array");if (fabs (m.im ∗ x) < ((13.78 ∗m.re − 10.8) ∗m.re + 3.9)) Dn up(z,nstop , D);else Dn down (z,nstop , D);

}This code is used in section 144.

151. OK, Here we go. We need to start up the arrays. First, recall (page 128 Bohren andHuffman) that

ψn(x) = xjn(x) and ξn(x) = xjn(x) + ixyn(x)

where jn and yn are spherical Bessel functions. The first few terms may be worked out as,

ψ0(x) = sinx and ψ1(x) =sinxx− cosx

andξ0(x) = ψ0 + i cosx and ξ1(x) = ψ1 + i

[cosxx

+ sinx]

〈Prepare to sum over all nstop terms 151 〉 ≡psi0 = sin (x);psi1 = psi0 /x− cos (x);xi0 = cset (psi0 , cos (x));xi1 = cset (psi1 , cos (x)/x+ sin (x));∗qsca = 0.0;∗g = 0.0;∗qext = 0.0;sign = 1;qbcalc = cset (0.0, 0.0);anm1 = cset (0.0, 0.0);bnm1 = cset (0.0, 0.0);

This code is used in section 144.

Page 46: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

46 Mie Scattering (Version 1.0): ARBITRARY SPHERES

152. The main equations for an and bn in Bohren and Huffman Equation (4.88).

an =

[Dn(mx)/m+ n/x

]ψn(x)− ψn−1(x)[

Dn(mx)/m+ n/x]ξn(x)− ξn−1(x)

and

bn =

[mDn(mx) + n/x

]ψn(x)− ψn−1(x)[

mDn(mx) + n/x]ξn(x)− ξn−1(x)

〈Establish an and bn 152 〉 ≡if (m.re ≡ 0.0) {

an = csdiv (n ∗ psi1 /x− psi0 , csub(csmul (n/x, xi1 ), xi0 ));bn = csdiv (psi1 , xi1 );

}else if (m.im ≡ 0.0) {

z1 .re = D[n].re/m.re + n/x;an = csdiv (z1 .re ∗ psi1 − psi0 , csub(csmul (z1 .re , xi1 ), xi0 ));z1 .re = D[n].re ∗m.re + n/x;bn = csdiv (z1 .re ∗ psi1 − psi0 , csub(csmul (z1 .re , xi1 ), xi0 ));

}else {

z1 = cdiv (D[n],m);z1 .re += n/x;an = cdiv (cset (z1 .re ∗ psi1 − psi0 , z1 .im ∗ psi1 ), csub(cmul (z1 , xi1 ), xi0 ));z1 = cmul (D[n],m);z1 .re += n/x;bn = cdiv (cset (z1 .re ∗ psi1 − psi0 , z1 .im ∗ psi1 ), csub(cmul (z1 , xi1 ), xi0 ));

}This code is used in section 144.

an : struct complex, §145.anm1 : struct complex, §145.bn : struct complex, §145.bnm1 : struct complex, §145.cdiv : struct complex, §61.cmul : struct complex, §59.complex: struct, §32.cos , <math.h>.csdiv : struct complex, §72.cset : struct complex, §36.csmul : struct complex, §68.csub : struct complex, §57.

D: struct complex ∗, §145.Dn down : void, §131.Dn up : void, §128.fabs , <math.h>.g: double ∗, §143.im : double, §32.m: struct complex, §143.mie error : static void, §117.n: long, §145.new carray : struct complex ∗,§106.

nstop : long, §145.

psi0 : double, §145.psi1 : double, §145.qbcalc : struct complex, §145.qext : double ∗, §143.qsca : double ∗, §143.re : double, §32.sign : long, §145.sin , <math.h>.x: double, §143.xi0 : struct complex, §145.xi1 : struct complex, §145.z1 : struct complex, §145.

Page 47: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): ARBITRARY SPHERES 47

153. The scattering matrix is given by Equation 4.74 in Bohren and Huffman. Namely,

S1 =∑n

2n+ 1n(n+ 1)

(anπn + bnτn)

andS2 =

∑n

2n+ 1n(n+ 1)

(anτn + bnπn)

Furthermore, equation 4.47 in Bohren and Huffman states

πn =2n− 1n− 1

µπn−1 −n

n− 1πn−2

andτn = nµπn − (n+ 1)πn−1

〈Calculate phase function for each angle 153 〉 ≡for (k = 0; k < nangles ; k++) {

factor = (2.0 ∗ n+ 1.0)/(n+ 1.0)/n;tau [k] = n ∗mu [k] ∗ pi1 [k]− (n+ 1) ∗ pi0 [k];alpha = factor ∗ pi1 [k];beta = factor ∗ tau [k];s1 [k].re += alpha ∗ an .re + beta ∗ bn .re ;s1 [k].im += alpha ∗ an .im + beta ∗ bn .im ;s2 [k].re += alpha ∗ bn .re + beta ∗ an .re ;s2 [k].im += alpha ∗ bn .im + beta ∗ an .im ;

}for (k = 0; k < nangles ; k++) {

factor = pi1 [k];pi1 [k] = ((2.0 ∗ n+ 1.0) ∗mu [k] ∗ pi1 [k]− (n+ 1.0) ∗ pi0 [k])/n;pi0 [k] = factor ;

}This code is used in section 144.

154. From page 120 of Bohren and Huffman the anisotropy is given by

Qsca〈cos θ〉 =4x2

[ ∞∑n=1

n(n+ 2)n+ 1

Re{ana∗n+1 + bnb∗n+1}+

∞∑n=1

2n+ 1n(n+ 1)

Re{anb∗n}]

For computation purposes, this must be rewritten as

Qsca〈cos θ〉 =4x2

[ ∞∑n=2

(n2 − 1)n

Re{an−1a∗n + bn−1b

∗n}+

∞∑n=1

2n+ 1n(n+ 1)

Re{anb∗n}]

From page 122 we find an expression for the backscattering efficiency

Qback =σbπa2

=1x2

∣∣∣∣∣∞∑n=1

(2n+ 1)(−1)n(an − bn)

∣∣∣∣∣2

Page 48: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

48 Mie Scattering (Version 1.0): ARBITRARY SPHERES

From page 103 we find an expression for the scattering cross section

Qsca =σsπa2

=2x2

∞∑n=1

(2n+ 1)(|an|2 + |bn|2)

The total extinction efficiency is also found on page 103

Qext =σtπa2

=2x2

∞∑n=1

(2n+ 1) Re(an + bn)

〈 Increment cross sections 154 〉 ≡factor = 2.0 ∗ n+ 1.0;∗g += (n− 1.0/n) ∗ (anm1 .re ∗ an .re + anm1 .im ∗ an .im + bnm1 .re ∗ bn .re + bnm1 .im ∗ bn .im );∗g += factor /n/(n+ 1.0) ∗ (an .re ∗ bn .re + an .im ∗ bn .im );∗qsca += factor ∗ (cnorm (an ) + cnorm (bn ));∗qext += factor ∗ (an .re + bn .re );sign ∗= −1;qbcalc .re += sign ∗ factor ∗ (an .re − bn .re );qbcalc .im += sign ∗ factor ∗ (an .im − bn .im );

This code is used in section 144.

alpha : double, §145.an : struct complex, §145.anm1 : struct complex, §145.beta : double, §145.bn : struct complex, §145.bnm1 : struct complex, §145.cnorm : double, §46.factor : double, §145.

g: double ∗, §143.im : double, §32.k: long, §145.mu : double ∗, §143.n: long, §145.nangles : long, §143.pi0 : double ∗, §145.pi1 : double ∗, §145.

qbcalc : struct complex, §145.qext : double ∗, §143.qsca : double ∗, §143.re : double, §32.s1 : struct complex ∗, §143.s2 : struct complex ∗, §143.sign : long, §145.tau : double ∗, §145.

Page 49: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): ARBITRARY SPHERES 49

155. The recurrence relations for ψ and ξ depend on the recursion relations for the sphericalBessel functions (page 96 equation 4.11)

zn−1(x) + zn+1(x) =2n+ 1x

zn(x)

where zn might be either jn or yn. Thus

ψn+1(x) =2n+ 1x

ψn(x)− ψn−1(x) and ξn+1(x) =2n+ 1x

ξn(x)− ξn−1(x)

Furthermore,〈Prepare for the next iteration 155 〉 ≡

factor = (2.0 ∗ n+ 1.0)/x;xi = csub(csmul (factor , xi1 ), xi0 );xi0 = xi1 ;xi1 = xi ;psi = factor ∗ psi1 − psi0 ;psi0 = psi1 ;psi1 = xi1 .re ;anm1 = an ;bnm1 = bn ;

This code is used in section 144.

156. 〈Calculate Efficiencies 156 〉 ≡∗qsca ∗= 2/(x ∗ x);∗qext ∗= 2/(x ∗ x);∗g ∗= 4/(∗qsca )/(x ∗ x);∗qback = cnorm (qbcalc)/(x ∗ x);

This code is used in section 144.

157. 〈Free allocated memory 157 〉 ≡if (m.re > 0) free carray (D);if (nangles > 0) {

free darray (pi0 );free darray (pi1 );free darray (tau );

}This code is used in section 144.

Page 50: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

50 Mie Scattering (Version 1.0): EASY MIE

158. Easy Mie.Given the size and real index of refraction, calculate the scattering efficiency and the anisotropy

for a non-absorbing sphere. If the sphere is totally reflecting, then let the index of refraction beequal to zero.

To recover the scattering coefficient µs from the efficiency qsca just multiply qsca by thegeometric cross sectional area and the density of scatterers.

159. 〈Prototype for ez Mie 159 〉 ≡void ez Mie (double x,double n,double ∗qsca ,double ∗g)

This code is used in sections 116 and 160.

160. 〈Definition for ez Mie 160 〉 ≡〈Prototype for ez Mie 159 〉{

long nangles = 0;double ∗mu = Λ;struct complex ∗s1 = Λ;struct complex ∗s2 = Λ;struct complex m;double qext , qback ;

m.re = n;m.im = 0.0;Mie (x,m,mu ,nangles , s1 , s2 ,&qext , qsca ,&qback , g);

}This code is used in section 115.

an : struct complex, §145.anm1 : struct complex, §145.bn : struct complex, §145.bnm1 : struct complex, §145.cnorm : double, §46.complex: struct, §32.csmul : struct complex, §68.csub : struct complex, §57.D: struct complex ∗, §145.factor : double, §145.free carray : void, §108.

free darray : void, §10.g: double ∗, §143.im : double, §32.m: struct complex, §143.Mie : void, §143.n: long, §145.nangles : long, §143.pi0 : double ∗, §145.pi1 : double ∗, §145.psi : double, §145.psi0 : double, §145.

psi1 : double, §145.qback : double ∗, §143.qbcalc : struct complex, §145.qext : double ∗, §143.qsca : double ∗, §143.re : double, §32.tau : double ∗, §145.x: double, §143.xi : struct complex, §145.xi0 : struct complex, §145.xi1 : struct complex, §145.

Page 51: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): A DRIVER PROGRAM FOR MIE SCATTERING 51

161. A driver program for Mie scattering.This program assumes a sphere in a medium with index of refraction 1.0. If this is not the

case then the index of refraction of the sphere should be divided by the index of refraction ofthe medium. The wavelength should also be divided by the index of refraction of the medium aswell.

This program is intended to provide a convenient means for calculating Mie scattering param-eters. It reads from stdin and writes to stdout . Each line of stdin should contain one set of Mieparameters arranged as followsradius wavelength index.real index.imag density num.angleswhere

radius is the radius of the sphere [µm]wavelength is the wavelength in the medium [µm]index.real is the real refractive indexindex.imag is the imaginary refraction indexdensity is the sphere density per cubic micron [µm−3]num.angles is the number of angles to generate

Just create an empty file to simplify the Makefile〈 miemain.h 161 〉 ≡

162. The real program is here〈 miemain.c 162 〉 ≡〈 the include files 163 〉〈Definition for file error 164 〉int main (int argc , char ∗∗argv ){〈Declare Mie variables 165 〉〈Get the arguments 166 〉while (¬feof (stdin )) {〈Print header 178 〉〈Read Mie Parameters 168 〉〈Calculate x 169 〉〈Allocate angle based arrays 176 〉Mie (x,m,mu ,nangles , s1 , s2 ,&qext ,&qsca ,&qback ,&g);〈Print summary 179 〉〈Print phase function 180 〉〈Free angle based arrays 177 〉

}}

163. 〈 the include files 163 〉 ≡#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include "array.h"

#include "complex.h"

#include "mie.h"

This code is used in section 162.

Page 52: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

52 Mie Scattering (Version 1.0): A DRIVER PROGRAM FOR MIE SCATTERING

164. 〈Definition for file error 164 〉 ≡static void file error (int aline ){

if (feof (stdin )) exit (1);if (ferror (stdin )) {

fprintf (stderr , "Some (bad) file error encountered on line %d", aline );exit (1);

}}

This code is used in section 162.

165. Variables.〈Declare Mie variables 165 〉 ≡

double pi = 3.14159265358979;double radius , lambda , n real , n imag , density , area ;long nangles , i, fp ;struct complex m;struct complex ∗s1 = Λ;struct complex ∗s2 = Λ;double ∗parallel = Λ;double ∗perpen = Λ;double ∗phasefn = Λ;double ∗mu = Λ;double ∗weights = Λ;double x, qext , qsca , qback , g;long line number = 1;FILE ∗f ;

This code is used in section 162.

complex: struct, §32.exit , <stdlib.h>.feof , <stdio.h>.ferror , <stdio.h>.FILE, <stdio.h>.fprintf , <stdio.h>.g: double ∗, §159.

m: struct complex, §160.Mie : void, §143.mu : double ∗, §160.nangles : long, §160.qback : double, §160.qext : double, §160.qsca : double ∗, §159.

s1 : struct complex ∗, §160.s2 : struct complex ∗, §160.stderr , <stdio.h>.stdin , <stdio.h>.stdout , <stdio.h>.x: double, §159.

Page 53: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): A DRIVER PROGRAM FOR MIE SCATTERING 53

166. If there is more than one argument then open the second which is presumably the filenameas stdin , otherwise just read from stdin . Don’t do anything with stdout .〈Get the arguments 166 〉 ≡

if (argc > 1) {f = freopen (argv [1], "r", stdin );if (f ≡ Λ) {

printf ("Usage:\r mie filename\n");exit (1);

}printf ("Source File: %s\n", argv [1]);

}This code is used in section 162.

167. 〈 check file error 167 〉 ≡if (fp ≡ 0) exit (1);file error (line number );

This code is used in sections 170, 171, 172, 173, 174, and 175.

168. Here is where the parameters for the Mie scattering calculation are read.〈Read Mie Parameters 168 〉 ≡〈Read sphere radius 170 〉〈Read wavelength 171 〉〈Read real index 172 〉〈Read imaginary index 173 〉〈Read density 174 〉〈Read number of angles 175 〉scanf ("\n");

This code is used in section 162.

169. 〈Calculate x 169 〉 ≡x = 2 ∗ radius ∗ pi/lambda ;

This code is used in section 162.

170. 〈Read sphere radius 170 〉 ≡fp = scanf (" %lf",&radius );〈 check file error 167 〉if (radius ≤ 0) {

printf ("Negative sphere radius in line %ld\n", line number );scanf ("\n");

}This code is used in section 168.

171. 〈Read wavelength 171 〉 ≡fp = scanf (" %lf",&lambda );〈 check file error 167 〉if (lambda ≤ 0) {

printf ("Negative wavelength in line %ld\n", line number );scanf ("\n");

}This code is used in section 168.

Page 54: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

54 Mie Scattering (Version 1.0): A DRIVER PROGRAM FOR MIE SCATTERING

172. 〈Read real index 172 〉 ≡fp = scanf (" %lf",&m.re );〈 check file error 167 〉if (m.re < 0) {

printf ("Negative real index of refraction in line %ld\n", line number );scanf ("\n");

}This code is used in section 168.

173. 〈Read imaginary index 173 〉 ≡fp = scanf (" %lf",&m.im );〈 check file error 167 〉if (m.im > 0) {

printf ("Positive imag index of refraction in line %ld\n", line number );printf ("it should be less than zero for absorbing spheres\n");scanf ("\n");

}This code is used in section 168.

174. 〈Read density 174 〉 ≡fp = scanf (" %lf",&density );〈 check file error 167 〉if (density ≤ 0) {

printf ("Non−positive density in line %ld\n", line number );scanf ("\n");

}This code is used in section 168.

175. 〈Read number of angles 175 〉 ≡fp = scanf (" %ld",&nangles );〈 check file error 167 〉if (nangles < 0) {

printf ("Negative number of angles in line %ld\n", line number );scanf ("\n");

}This code is used in section 168.

argc : int, §162.argv : char ∗∗, §162.density : double, §165.exit , <stdlib.h>.f : FILE ∗, §165.file error : static void, §164.fp : long, §165.

freopen , <stdio.h>.im : double, §32.lambda : double, §165.line number : long, §165.m: struct complex, §165.nangles : long, §165.pi : double, §165.

printf , <stdio.h>.radius : double, §165.re : double, §32.scanf , <stdio.h>.stdin , <stdio.h>.stdout , <stdio.h>.x: double, §165.

Page 55: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): A DRIVER PROGRAM FOR MIE SCATTERING 55

176. 〈Allocate angle based arrays 176 〉 ≡if (nangles > 0) {

mu = new darray (nangles );for (i = 0; i < nangles ; i++) mu [i] = cos (2 ∗ pi/nangles ∗ i);parallel = new darray (nangles );perpen = new darray (nangles );phasefn = new darray (nangles );s1 = new carray (nangles );s2 = new carray (nangles );

}This code is used in section 162.

177. 〈Free angle based arrays 177 〉 ≡if (nangles > 0) {

free darray (mu );free darray (parallel );free darray (perpen );free darray (phasefn );free carray (s1 );free carray (s2 );

}This code is used in section 162.

178. Print a header then the angles. Make sure everything lines up.〈Print header 178 〉 ≡

printf ("* Mie Scattering Version 1.0 by Scott Prahl\n");printf ("* Oregon Medical Laser Center\n");printf ("* [email protected]\n");printf ("*\n");printf ("* r0\t lambda\t m.re\t m.im\t N\t g");printf ("\t mu_ext\t mu_s\n");printf ("*micron\t [micron]\t \t \t#/micron^3\t ");printf ("\t [1/cm]\t [1/cm] \n");

This code is used in section 162.

179. 〈Print summary 179 〉 ≡area = 3.1415926 ∗ radius ∗ radius ;printf ("%9.5e\t %9.5e\t ", radius , lambda );printf ("%9.5e\t %9.5e\t ",m.re ,m.im );printf ("%9.5e\t %9.5e\t %9.5e\t ", density , g, density ∗ qext ∗ area );printf ("%9.5e\n", density ∗ qsca ∗ area );

This code is used in section 162.

180. 〈Print phase function 180 〉 ≡if (nangles > 0) {

for (i = 0; i < nangles ; ++i) {parallel [i] = 4 ∗ cnorm (s2 [i])/(x ∗ x ∗ qsca );perpen [i] = 4 ∗ cnorm (s1 [i])/(x ∗ x ∗ qsca );phasefn [i] = (parallel [i] + perpen [i])/2;

Page 56: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

56 Mie Scattering (Version 1.0): A DRIVER PROGRAM FOR MIE SCATTERING

}printf ("*\n");printf ("* natural perpen parallel\n");printf ("* mu (|s1|^2+|S2|^2)/2 |S1|^2 |S2|^2\n");for (i = 0; i < nangles ; i++)

printf ("%9.5e\t %9.5e\t %9.5e\t %9.5e\n",mu [i], phasefn [i], perpen [i], parallel [i]);}

This code is used in section 162.

area : double, §165.cnorm : double, §46.cos , <math.h>.density : double, §165.free carray : void, §108.free darray : void, §10.g: double, §165.i: long, §165.im : double, §32.lambda : double, §165.

m: struct complex, §165.mu : double ∗, §165.nangles : long, §165.new carray : struct complex ∗,§106.

new darray : double ∗, §8.parallel : double ∗, §165.perpen : double ∗, §165.phasefn : double ∗, §165.

pi : double, §165.printf , <stdio.h>.qext : double, §165.qsca : double, §165.radius : double, §165.re : double, §32.s1 : struct complex ∗, §165.s2 : struct complex ∗, §165.x: double, §165.

Page 57: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

Mie Scattering (Version 1.0): INDEX 57

181. Index. Here is a cross-reference table for the Mie scattering program. All sections inwhich an identifier is used are listed with that identifier, except that reserved words are indexedonly when they appear in format definitions, and the appearances of identifiers in section namesare not indexed. Underlined entries correspond to where the identifier was declared. Errormessages and a few other things like “ASCII code dependencies” are indexed here too.

Page 58: Mie Scattering (Version 1.0): EQUATIONS FOR MIE ... - … · Mie Scattering (Version 1.0): EQUATIONS FOR MIE SCATTERING 1 1. Equations for Mie scattering. The index of refraction

58 Mie Scattering (Version 1.0): INDEX