Skip to content

Commit b3afd67

Browse files
committed
added information on broadcasting and array shapes to module docstring
1 parent 1ecae05 commit b3afd67

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

pymie/mie.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,93 @@
3131
3232
Key reference for multilayer algorithm is [3]_
3333
34+
Some notes on array dimensions and broadcasting:
35+
36+
- Nearly all calculations are vectorized. Let "..." denote the dimensions
37+
corresponding to parameters of the calculations. For example, we might be
38+
interested in calculating scattering quantities as a function of wavelength
39+
and volume fraction (volume fraction can enter into a calculation
40+
indirectly through an effective refractive index). Then "..." might
41+
represent the volume fraction and wavelength dimensions.
42+
43+
- m and x must be specified as at least 2D arrays. The shapes are
44+
m: (..., num_layers)
45+
x: (..., num_layers)
46+
where num_layers is the number of layers of a multilayer particle, and
47+
"..." means at least one other dimension (wavelength). If specified with
48+
shape (1, 1), the calculation will be done at a single, scalar value of m
49+
and of x. This situation would correspond to a single wavelength and a
50+
single, non-layered sphere.
51+
52+
- Angles (thetas and phis) must be specified with shape
53+
thetas: ([angle_leading_dims], num_thetas)
54+
phis: ([angle_leading_dims], num_phis)
55+
where [angle_leading_dims] is a subset of the leading dimensions of m/x.
56+
57+
- For example, if m has shape
58+
m: (num_volume_fractions, num_wavelengths, num_layers),
59+
then thetas can have shape
60+
thetas: (num_thetas) or
61+
thetas: (num_wavelengths, num_thetas) or
62+
thetas: (num_volume_fractions, num_wavelengths, num_thetas).
63+
The same is true of phi, but with num_phis instead of num_thetas.
64+
Therefore, the angles can be a function of wavelength, for example. As
65+
long as angle_leading_dims are specified in the same order as in "...",
66+
thetas and phis will broadcast correctly, once the dimensions of other
67+
quantities have been expanded (see below)
68+
69+
- Intermediate calculations: quantities to be used in calculations with
70+
angles have their dimensions expanded to include theta (and phis). For
71+
example, we might expand x to the following:
72+
x: (..., 1)
73+
to broadcast with the thetas array. If phis is specified, we expand x to
74+
x: (..., 1, 1)
75+
Other intermediate arrays are expanded to the same dimensions for
76+
broadcasting -- but not necessarily the same shapes, because we want to
77+
conserve memory.
78+
79+
- Intermediate calculations: calculations that involve summing over a series
80+
will have an "order" dimensions, corresponding to the order of the
81+
coefficients used in the series. We add this order dimension to the end of
82+
the array, since we want to remove it after we sum over it. In this case,
83+
we might expand x as follows:
84+
x: (..., n_max)
85+
where n_max is the maximum order. If the calculation also involves the
86+
angle theta, x would be expanded as
87+
x: (..., 1, n_max)
88+
and if phis are involved as well,
89+
x: (..., 1, 1, n_max)
90+
91+
- Broadcasting: All functions broadcast over the leading dimensions of m and
92+
x (the "..." above). Thus, outputs will contain the same dimensions as in
93+
"..." and possibly others that have been added (like polarization). A
94+
calculation done for a single value of m and of x -- shape (1, 1) for both
95+
-- will retain the singlet dimension corresponding to the first 1. This
96+
dimension can later be removed by ".squeeze()" but we do not squeeze by
97+
default because doing so would lead to inconsistent numbers of dimensions
98+
between, for example, single-wavelength and multi-wavelength calculations.
99+
100+
- Output shapes are as follows. [] indicates optional
101+
scat. coefficients: (2, ..., n_max)
102+
diff. cross-secs: (num_polarizations, ..., num_thetas, [num_phis])
103+
integrated cross-secs: (...,)
104+
scat. matrix elements: (..., num_thetas)
105+
106+
- Outputs generally do not contain a layers dimension because most
107+
calculations report scattering quantities for the entire sphere, not
108+
individual layers within it.
109+
110+
- The broadcasting approach has its limitations, primarily because we choose
111+
the maximum order (nstop) to calculate the Mie coefficients based on the
112+
largest value of x in the array of size parameters. Therefore, in
113+
calculations over a wide range of size parameters, the coefficients
114+
corresponding to every size parameter are expanded to the same (large)
115+
order -- which is not only inefficient, but can also lead to numerical
116+
instabilities for small x's in the size parameter array. One way around
117+
this limitation would be to use ragged arrays when expanding x to (...,
118+
n_max), but doing this efficiently would require installing an extension to
119+
numpy like Awkward Array.
120+
34121
References
35122
----------
36123
[1] Bohren, C. F. and Huffman, D. R. "Absorption and Scattering of Light by

0 commit comments

Comments
 (0)