Search:

Return to previous page

Contents of file 'magbragg/magbragg.w':



    1   % File:        magbragg.w [CWEB source code]
    2   % Created:     October 28, 2002 [v.1.0]
    3   % Last change: December 18, 2011 [v.1.44]
    4   % Author:      Fredrik Jonsson
    5   % Description: The CWEB source code for the MAGBRAGG simulator of nonlinear
    6   %              magneto-optical Bragg gratings. For information on the CWEB
    7   %              programming language, see http://www.literateprogramming.com.
    8   % Compilation: Compile this program by using the enclosed Makefile, or use
    9   %              the blocks of the Makefile as listed in section five of the
   10   %              documentation (file magbragg.ps or magbragg.pdf). The C source
   11   %              code (as generated from this CWEB code) conforms to the ANSI
   12   %              standard for the C programming language (which is equivalent
   13   %              to the ISO C90/C99 standard for C).
   14   %
   15   % Copyright (C) 2002--2011, Fredrik Jonsson
   16   %
   17   \input epsf
   18   \def\version{1.44}
   19   \def\lastrevdate{January 10, 2007}
   20   \font\eightcmr=cmr8
   21   \font\tensc=cmcsc10
   22   \font\eightcmssq=cmssq8
   23   \font\eightcmssqi=cmssqi8
   24   \font\twentycmcsc=cmcsc10 at 20 truept
   25   \def\magbragg{{\eightcmr MAGBRAGG\spacefactor1000}}
   26   \def\poincare{{\eightcmr POINCARE\spacefactor1000}}
   27   \def\ANSI{{\eightcmr ANSI\spacefactor1000}} % The language standard we stick to
   28   \def\SI{{\eightcmr SI\spacefactor1000}}   % Another standard for physical units
   29   \def\GNU{{\eightcmr GNU\spacefactor1000}}       % GNU is Not Unix
   30   \def\GCC{{\eightcmr GCC\spacefactor1000}}       % The GNU C-compiler
   31   \def\CEE{{\eightcmr C\spacefactor1000}}         % The C programming language
   32   \def\ANSICEE{{\eightcmr ANSI~C\spacefactor1000}}% The ANSI-C standard language
   33   \def\CWEB{{\eightcmr CWEB\spacefactor1000}}     % The CWEB programming language
   34   \def\MATLAB{{\eightcmr MATLAB\spacefactor1000}} % The MATLAB ditto
   35   \def\UNIX{{\eightcmr UNIX\spacefactor1000}}
   36   \def\CYGWIN{{\eightcmr CYGWIN\spacefactor1000}}
   37   \def\CTANGLE{{\eightcmr CTANGLE\spacefactor1000}}
   38   \def\CWEAVE{{\eightcmr CWEAVE\spacefactor1000}}
   39   \def\OSX{{OS\,X}}
   40   \def\re{\mathop{\rm Re}\nolimits} % The real part of a complex number
   41   \def\im{\mathop{\rm Im}\nolimits} % The imaginary part of a complex number
   42   \def\dollar{\char'044}             % The `$' character
   43   \def\tothepower{\char'136}         % The `^' character
   44   \def\onehalf{{\textstyle{{1}\over{2}}}}
   45   \def\threefourth{{\textstyle{{3}\over{4}}}}
   46   \def\endalg{\vrule height 1.4ex width .6ex depth .4ex} % Rectangular bullet
   47   \def\ie{i.\thinspace{e.}~\ignorespaces}
   48   \def\eg{e.\thinspace{g.}~\ignorespaces}
   49   \let\,\thinspace
   50   %% \def\subsection[#1]{\goodbreak\noindent{\it #1}\par\nobreak\noindent}
   51   %
   52   % Define a handy macro for listing the steps of an algorithm.
   53   %
   54   \newdimen\aitemindent \aitemindent=26pt
   55   \newdimen\aitemleftskip \aitemleftskip=36pt
   56   \def\aitem[#1]{\smallbreak\noindent\hbox to 10pt{}%
   57     \hbox to\aitemindent{\bf #1\hfill}%
   58     \hangindent\aitemleftskip\ignorespaces}
   59   %
   60   % Define a handy macro for bibliographic references.
   61   %
   62   \newdimen\refitemindent \refitemindent=18pt
   63   \def\refitem[#1]{\smallbreak\noindent%
   64     \hbox to\refitemindent{[#1]\hfill}%
   65     \hangindent\refitemindent\ignorespaces}
   66   %
   67   % Define a handy macro for nicely typeset variable descriptions.
   68   %
   69   \newdimen\varitemindent \varitemindent=100pt
   70   \def\varitem[#1]#2{\smallbreak\noindent\hbox to 20pt{}%
   71     \hbox to\varitemindent{#1\hfill}%
   72     \hangindent 120pt\ignorespaces#2\par}
   73   %
   74   % Define a handy macro for the list of program revisions.
   75   %
   76   \newdimen\citemindent \citemindent=80pt
   77   \newdimen\citemleftskip \citemleftskip=90pt
   78   \def\citem[#1]{\smallbreak\noindent\hbox to 10pt{}%
   79     \hbox to\citemindent{\bf #1\hfill}%
   80     \hangindent\citemleftskip\ignorespaces}
   81   \def\citindent{\smallbreak\noindent\hbox to 10pt{}%
   82     \hbox to\citemindent{\hfil}%
   83     \hangindent\citemleftskip\ignorespaces}
   84   %
   85   % Define the \beginvrulealign and \endvrulealign macros as described in
   86   % Donald Knuth's The TeXbook, Appendix D: Dirty Tricks. These macros are
   87   % used in typesetting nicely looking tables.
   88   %
   89   \def\beginvrulealign{\setbox0=\vbox\bgroup}
   90   \def\endvrulealign{\egroup % now \box0 holds the entire alignment
   91     \setbox0=\vbox{\setbox2=\hbox{\vrule height\ht0 depth\dp0 width0pt}
   92       \unvbox0 \setbox0=\lastbox % now \box0 is the bottom row
   93       \nointerlineskip \copy0 % put it back
   94       \global\setbox1=\hbox{} % initialize box that will contain rules
   95       \setbox4=\hbox{\unhbox0 % now open up the bottom row
   96         \loop \skip0=\lastskip \unskip % remove tabskip glue
   97         \advance\skip0 by-.4pt % rules are .4 pt wide
   98         \divide\skip0 by 2
   99         \global\setbox1=\hbox{\hskip\skip0\vrule\hskip\skip0
  100           \unhbox2\unhbox1}%
  101         \setbox2=\lastbox % remove alignment entry
  102         \ifhbox2 \setbox2=\hbox{\kern\wd2}\repeat}}%
  103     \hbox{\rlap{\box0}\box1}} % superimpose the alignment on the rules
  104   
  105   \datethis
  106   
  107   @*Introduction.
  108   \vskip 120pt
  109   \centerline{\twentycmcsc MagBragg}
  110   \vskip 20pt
  111   \centerline{A simulator of nonlinear magneto-optical Bragg gratings}
  112   \vskip 2pt
  113   \centerline{(Version \version\ of \lastrevdate)}
  114   \vskip 10pt
  115   \centerline{Written by Fredrik Jonsson}
  116   \vskip 80pt
  117   \noindent
  118   This \CWEB\footnote{${}^\dagger$}{For information on the \CWEB\ programming
  119   language by Donald E.~Knuth, as well as samples of \CWEB\ programs, see
  120   \.{http://www-cs-faculty.stanford.edu/\~\ \kern -5pt knuth/cweb.html}.
  121   For general information on literate programming, see
  122   \.{http://www.literateprogramming.com}.} computer program calculates
  123   reflection and transmission spectra of nonlinear magneto-optical Bragg
  124   gratings, in a stratified geometry where the material parameters vary only
  125   in one Cartesian coordinate.
  126   The \magbragg\ program also simulates the propagation of the electromagnetic
  127   field of an optical wave as it traverses a magneto-optical Bragg grating, in
  128   linear as well as nonlinear optical regimes.
  129   
  130   Strictly speaking, in a linear-optical domain a forward algorithm would just as
  131   fine as a backward one; however, for nonlinear optical problems, it often (as
  132   in this particular case) turns out that it is easier to compute the inverse
  133   problem, that is to say, to compute the input that corresponds to a certain
  134   given output. This is the case for, for example, optical bistability, where a
  135   given input intensity and ellipticity of the input optical wave for certain
  136   configurations correspond to a multiple-valued optical output. This means that
  137   we are not always on safe ground when it comes to the evaluation of output as
  138   function of input; meantime it makes perfectly sense to calculate the
  139   single-valued input as function of optical output.
  140   This program, in particular, is formulated in terms of the inverse problem, and
  141   hence the input parameters to the program are partly given in terms of the
  142   optical output of the magneto-optical Bragg grating.
  143   The algorithm behind the program was published as F.~Jonsson and C.~Flytzanis,
  144   Physical Review Letters {\bf 96}, 063902 (2006).
  145   \bigskip
  146   \noindent Copyright \copyright\ Fredrik Jonsson, 2002--2007.
  147   All rights reserved.
  148   \vfill
  149   
  150   @*The CWEB programming language.
  151   For the reader who might not be familiar with the concept of the
  152   \CWEB\ programming language, the following citations hopefully will
  153   be useful. For further information, as well as freeware compilers for
  154   compiling \CWEB\ source code, see \.{http://www.literateprogramming.com}.
  155   \bigskip
  156   
  157   {\narrower\narrower\narrower\narrower\eightcmssqi\noindent
  158   I believe that the time is ripe for significantly better documentation of
  159   programs, and that we can best achieve this by considering programs to be
  160   works of literature. Hence, my title: `Literate Programming.'
  161   
  162   Let us change our traditional attitude to the construction of programs:
  163   Instead of imagining that our main task is to instruct a computer what to
  164   do, let us concentrate rather on explaining to human beings what we want
  165   a computer to do.
  166   
  167   The practitioner of literate programming can be regarded as an essayist,
  168   whose main concern is with exposition and excellence of style. Such an
  169   author, with thesaurus in hand, chooses the names of variables carefully
  170   and explains what each variable means. He or she strives for a program
  171   that is comprehensible because its concepts have been introduced in an
  172   order that is best for human understanding, using a mixture of formal and
  173   informal methods that reinforce each other.
  174   \smallskip
  175   {\eightcmssq --\,Donald Knuth,}
  176   {\eightcmssqi The CWEB System of Structured Documentation}
  177   {\eightcmssq (Addison-Wesley, Massachusetts, 1994)}
  178   }
  179   \bigskip
  180   
  181   {\narrower\narrower\narrower\narrower\eightcmssqi\noindent
  182   The philosophy behind CWEB is that an experienced system programmer, who
  183   wants to provide the best possible documentation of his or her software
  184   products, needs two things simultaneously: a language like \TeX\ for
  185   formatting, and a language like C for programming. Neither type of language
  186   can provide the best documentation by itself; but when both are appropriately
  187   combined, we obtain a system that is much more useful than either language
  188   separately.
  189   
  190   The structure of a software program may be thought of as a `WEB' that is
  191   made up of many interconnected pieces. To document such a program we want to
  192   explain each individual part of the web and how it relates to its neighbors.
  193   The typographic tools provided by \TeX\ give us an opportunity to explain the
  194   local structure of each part by making that structure visible, and the
  195   programming tools provided by languages like C make it possible for us to
  196   specify the algorithms formally and unambiguously. By combining the two,
  197   we can develop a style of programming that maximizes our ability to perceive
  198   the structure of a complex piece of software, and at the same time the
  199   documented programs can be mechanically translated into a working software
  200   system that matches the documentation.
  201   
  202   Besides providing a documentation tool, CWEB enhances the C language by
  203   providing the ability to permute pieces of the program text, so that a
  204   large system can be understood entirely in terms of small sections and
  205   their local interrelationships. The CTANGLE program is so named because
  206   it takes a given web and moves the sections from their web structure into
  207   the order required by C; the advantage of programming in CWEB is that the
  208   algorithms can be expressed in ``untangled'' form, with each section
  209   explained separately. The CWEAVE program is so named because it takes a
  210   given web and intertwines the \TeX\ and C portions contained in each
  211   section, then it knits the whole fabric into a structured document.
  212   \smallskip
  213   {\eightcmssq --\,Donald Knuth, ``Literate Programming'', in}
  214   {\eightcmssqi Literate Programming}
  215   {\eightcmssq (CSLI Lecture Notes, Stanford, 1992)}
  216   }
  217   
  218   @*Theory of nonlinear magneto-optical Bragg gratings.
  219   The algorithm used for the simulation is based on the inverse problem of
  220   nonlinear optical gratings,
  221   where the transmitted optical field is used as input to the algorithm,
  222   which successively calculates the intra-grating optical fields backwards
  223   through the structure, finally ending up with the corresponding incident field.
  224   The analysis is here for the sake of simplicity restricted to infinite
  225   plane waves under assumption of the slowly varying envelope approximation.
  226   The conventions of notation for the discrete layers in the structure of
  227   analysis are shown in Fig.~1, in which $N-1$ layers of nonlinear
  228   magneto-optical media are separated by their boundaries at $z=z_1,\ldots,z_N$.
  229   
  230   \bigskip
  231   \centerline{\epsfxsize=86mm\epsfbox{figures/geom/geom.1}}\smallskip
  232   {\narrower\narrower\noindent{\bf Figure 1.} The geometry of the discretized
  233   model of the magneto-optical Bragg grating, in the Faraday configuration with
  234   the static magnetic ${\bf B}_0=B^z_0{\bf e}_z$ applied in the direction of
  235   wave propagation. The grating consists of $N$ optically homogeneous layers
  236   with $N+1$ discrete interfaces located at spatial coordinates $z_k$, for
  237   $k=1,2,\ldots,N$, with the optical properties of each layer described by the
  238   optical susceptibility tensors $\chi^{\rm ee}_{ij}$ and
  239   $\chi^{\rm eeee}_{ijkl}$ and their magneto-optical counter-parts
  240   $\chi^{\rm eem}_{ijk}$ and $\chi^{\rm eeeem}_{ijklm}$.\par}
  241   \bigskip
  242   
  243   @ Discretization of the problem. In each homogeneous layer $z_k<z<z_{k+1}$,
  244   $k=1,2,\ldots,N-1$, the components of the plane-parallel electromagnetic field
  245   ${\bf E}(z,t)=\re[{\bf E}_{\omega}\exp(-i\omega t)]$ propagate collinearly
  246   with an externally applied static magnetic field ${\bf B}_0=B^z_0{\bf e}_z$,
  247   and the local constitutive relation for the electric polarization density
  248   ${\bf P}(z,t)=\re[{\bf P}_{\omega}\exp(-i\omega t)]$ of the medium
  249   is~[1]
  250   $$
  251   \eqalign{
  252     {\bf P}_{\omega}=\varepsilon_0[&\chi^{{\rm ee}}_{xx} {\bf E}_{\omega}
  253       +\chi^{{\rm eem}}_{xyz} {\bf E}_{\omega}\times{\bf B}_0\cr
  254      &+(\chi^{{\rm eeee}}_{xxxx}-\chi^{{\rm eeee}}_{xyyx})
  255         ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}
  256       +\chi^{{\rm eeee}}_{xyyx}
  257         ({\bf E}_{\omega}\cdot{\bf E}_{\omega}){\bf E}^*_{\omega}\cr
  258      &+\chi^{{\rm eeeem}}_{xyyyz}
  259         ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}\times{\bf B}_0
  260       +\chi^{{\rm eeeem}}_{xxxyz}{\bf E}_{\omega}
  261         ({\bf E}_{\omega}\cdot({\bf E}^*_{\omega}\times{\bf B}_0))].\cr
  262   }
  263   \eqno{(1)}
  264   $$
  265   In this expression, the spatial dependence of the fields and susceptibilities
  266   is omitted in notation, as is also any slow temporal variation of the fields;
  267   from now on each appearance of a field or susceptibility implicitly implies
  268   evaluation in respective layer of context. In each layer, the envelope of the
  269   electromagnetic field satisfies the autonomous nonlinear wave equation
  270   $$
  271     {{\partial^2{\bf E}_{\omega}}\over{\partial z^2}}
  272       +(\omega/c)^2{\bf E}_{\omega}
  273       =-\mu_0\omega^2{\bf P}_{\omega}.
  274   \eqno{(2)}
  275   $$
  276   The field is in each layer expressed in a circularly polarized basis
  277   ${\bf e}_{\pm}=({\bf e}_x \pm i{\bf e}_y)/\sqrt{2}$, with forward and
  278   backward traveling modes as a superposition
  279   $$
  280   \eqalign{
  281     {\bf E}_{\omega}&=
  282      [{\bf e}_+ E^{\rm f}_{k_+}(z) + {\bf e}_- E^{\rm f}_{k_-}(z)]
  283        \exp[i\omega n_k (z-z_k)/c]\cr
  284     &\qquad+[{\bf e}^*_+ E^{\rm b}_{k_+}(z) + {\bf e}^*_- E^{\rm b}_{k_-}(z)]
  285        \exp[-i\omega n_k (z-z_k)/c],\cr
  286   }
  287   \eqno{(3)}
  288   $$
  289   where $n_k=(1+\chi^{{\rm ee}}_{xx})^{1/2}$ are the linear refractive indices
  290   of the layers.
  291   We here adopt to the convention of circularly polarized field components
  292   that when looking into the oncoming wave, a left circularly polarized wave
  293   will have its vector of the electric field rotating with counterclockwise
  294   motion, while the corresponding vector of a right circularly polarized field
  295   will describe clockwise motion.
  296   This convention applies irregardless of whether we are looking into a forward
  297   propagating wave, that is to say looking in the negative $z$-direction, or
  298   looking into a backward propagating wave, in which case we instead look in the
  299   positive $z$-direction, along the $z$-axis. This convention conforms to the
  300   classical one as commonly used in optics~[5].
  301   Throughout this program, the notation $E^{\rm f}_{k_{\pm}}(z)$ is used to
  302   denote the left/right circularly polarized components of the forward traveling
  303   component of the electric field in the $k$th homogeneous layer, while
  304   $E^{\rm b}_{k_{\pm}}(z)$ in an analogous manner is used to denote the
  305   left/right circularly polarized components of the backward traveling component
  306   of the electric field, taking into account the previously described convention
  307   for circular polarization states.
  308   
  309   @ General solutions in the homogeneous layers.
  310   By inserting the form of the electric field as given by Eq.~(3) into the wave
  311   equation as given by Eq.~(1) under the constitutive relation given by Eq.~(1)
  312   and furthermore applying the slowly varying envelope approximation, the general
  313   solutions for the field components in loss-less media become~[1]
  314   $$
  315   \eqalignno{
  316     E^{\rm f}_{k_{\pm}}&=A^{\rm f}_{k_{\pm}}\exp[i(\omega/c)
  317       (\eta^{\rm f}_{k_{\pm}}\pm g_k)(z-z_k)+i\psi^{\rm f}_{k_{\pm}}],
  318   &(4{\rm a})\cr
  319     E^{\rm b}_{k_{\pm}}&=A^{\rm b}_{k_{\pm}}\exp[-i(\omega/c)
  320       (\eta^{\rm b}_{k_{\pm}}\mp g_k)(z-z_k)+i\psi^{\rm b}_{k_{\pm}}].
  321   &(4{\rm b})\cr
  322   }
  323   $$
  324   In these expressions $A^{\rm f,b}_{k_{\pm}}$ and $\psi^{\rm f,b}_{k_{\pm}}$
  325   are real constants of integration, determined by the boundary conditions of
  326   the $k$th layer, and $g_k=i\chi^{{\rm eem}}_{xyz}B^z_0/(2n_k)$ are the real
  327   linear magneto-optical gyration coefficients.
  328   In Eqs.~(4) the nonlinear optical and magneto-optical light-matter
  329   interactions are described by the field-dependent parameters
  330   $$
  331   \eqalignno{
  332     \eta^{\rm f}_{k_{\pm}}&=
  333       p_{k_{\pm}}(A^{{\rm f}\,2}_{k_{\pm}}+2A^{{\rm b}\,2}_{k_{\mp}})
  334       +q_{k_{\pm}}(A^{{\rm f}\,2}_{k_{\mp}}+A^{{\rm b}\,2}_{k_{\pm}}),
  335   &(5{\rm b})\cr
  336     \eta^{\rm b}_{k_{\pm}}&=
  337       p_{k_{\mp}}(A^{{\rm b}\,2}_{k_{\pm}}+2A^{{\rm f}\,2}_{k_{\mp}})
  338       +q_{k_{\mp}}(A^{{\rm b}\,2}_{k_{\mp}}+A^{{\rm f}\,2}_{k_{\pm}}),
  339   &(5{\rm b})\cr
  340   }
  341   $$
  342   where the coefficients $p_{k_{\pm}}$ and $q_{k_{\pm}}$ in the nonlinear
  343   susceptibility formalism~[3] are expressed as
  344   $$
  345   \eqalignno{
  346      p_{k_{\pm}}&=
  347        {{3}\over{8n_k}}[\chi^{{\rm eeee}}_{xxxx}-\chi^{{\rm eeee}}_{xyyx}
  348         \pm i(\chi^{{\rm eeeem}}_{xyyyz}-\chi^{{\rm eeeem}}_{xxxyz})B^z_0],
  349   &(6{\rm b})\cr
  350      q_{k_{\pm}}&=
  351        {{3}\over{8n_k}}[\chi^{{\rm eeee}}_{xxxx}+\chi^{{\rm eeee}}_{xyyx}
  352         \pm i(\chi^{{\rm eeeem}}_{xyyyz}+\chi^{{\rm eeeem}}_{xxxyz})B^z_0].
  353   &(6{\rm b})\cr
  354   }
  355   $$
  356   
  357   %\centerline{\epsfxsize=86mm\epsfbox{figures/geom/geom.2}}\smallskip
  358   %{\narrower\narrower\noindent{\bf Figure 2.} Closeup of the geometry of the
  359   %discretized model of the magneto-optical Bragg grating, illustrating the
  360   %convention of notation for the electric field of the optical wave taken
  361   %immediately to the left and right of the layer interfaces $z_k$.\par}
  362   
  363   @ Rotation of the polarization state across the homogeneous layers.
  364   The angle of rotation $\vartheta_k$ of the polarization ellipse of the
  365   forward traveling components around the $z$-axis in each layer is then
  366   $$
  367   \eqalign{
  368     \vartheta_k&={{\omega (z-z_k)}\over{2 n_k c}}[-i\chi^{{\rm eem}}_{xyz} B^z_0
  369       +(3/4)\chi^{{\rm eeee}}_{xyyx}(A^{{\rm f}\,2}_{k_+}-A^{{\rm f}\,2}_{k_-})
  370   %\cr&\quad
  371       +(3/8)(\chi^{{\rm eeee}}_{xxxx}-3\chi^{{\rm eeee}}_{xyyx})
  372         (A^{{\rm b}\,2}_{k_+}-A^{{\rm b}\,2}_{k_-})
  373   \cr&\quad
  374   %\cr&\quad
  375       -(3/4)i\chi^{{\rm eeeem}}_{xyyyz}
  376         (A^{{\rm f}\,2}_{k_+}+A^{{\rm f}\,2}_{k_-}) B^z_0
  377       +(3/8)i(\chi^{{\rm eeeem}}_{xxxyz}-3\chi^{{\rm eeeem}}_{xyyyz})
  378         (A^{{\rm b}\,2}_{k_+}+A^{{\rm b}\,2}_{k_-}) B^z_0].
  379   }
  380   \eqno{(7)}
  381   $$ % (Equation counterchecked to be OK July 29, 2004.)
  382   The first term in this expression describes linear Faraday rotation~[4] and
  383   leads to an effective Zeeman-like polarization state splitting of the doubly
  384   degenerate Bragg resonances. The second and third terms arise from optical
  385   Kerr-effect and lead to photo-induced modification of the ellipse rotation for
  386   forward and backward propagating waves respectively. Referring to the wave
  387   equation given by Eqs.~(1)--(2) these terms effectively act as to give
  388   photo-induced Stark-like shifts of the split Bragg resonances.
  389   Finally the fourth and fifth terms describe photo-induced magneto-optic
  390   Faraday rotation or equivalently photoinduced modification of the effective
  391   Zeeman-like splitting of the Bragg resonances. We note by passing that the
  392   third and fifth terms vanish whenever Kleinman symmetry~[3] holds.
  393   Moreover, from Eq.~(7) one obtains the Verdet coefficient~$V$ of the medium as
  394   $$
  395     V={{\omega\im[\chi^{{\rm eem}}_{xyz}]}\over{2 n_k c}},
  396   \eqno{(8)}
  397   $$
  398   describing the Faraday rotation angle per propagation length and static
  399   magnetic field intensity.
  400   
  401   @ Boundary conditions at the discrete interfaces. By neglecting any nonlinear
  402   effects at the discrete interfaces between the homogeneous layers, the
  403   continuity requirement of the transverse electromagnetic field across each
  404   interface is formulated by the boundary conditions
  405   $$
  406     \eqalignno{
  407      &E^{\rm f}_{k_{\pm}}(z_k)=
  408       \tau_{k_{\pm}} E^{\rm f}_{{k-1}_{\pm}}(z_k)
  409       \exp(i \omega n_{k-1} d_{k-1}/c)
  410       +\rho'_{k_{\mp}} E^{\rm b}_{k_{\mp}}(z_k),&(9{\rm a})\cr
  411      &E^{\rm b}_{k_{\mp}}(z_{k+1}) \exp(-i \omega n_k d_k/c)
  412       =\tau'_{{k+1}_{\mp}} E^{\rm b}_{{k+1}_{\mp}}(z_{k+1})
  413       +\rho_{{k+1}_{\pm}} E^{\rm f}_{k_{\pm}}(z_{k+1})
  414        \exp(i \omega n_k d_k/c),&(9{\rm b})\cr
  415     }
  416   $$
  417   for $k=1,2,\ldots,N-1$, where $d_k=z_{k+1}-z_k$ are the layer thicknesses,
  418   and where
  419   $$
  420     \eqalignno{
  421     \rho_{k_{\pm}}
  422       &={{n_{k-1}-n_k\pm(g_{k-1}-g_k)}\over{n_{k-1}+n_k\pm(g_{k-1}+g_k)}}
  423        =-\rho'_{k_{\mp}},
  424   &(10{\rm a})\cr
  425     \tau_{k_{\pm}}
  426       &={{2(n_{k-1}\pm g_{k-1})}\over{n_{k-1}+n_k\pm (g_{k-1}+g_k)}},
  427   &(10{\rm b})\cr
  428     \tau'_{k_{\mp}}
  429       &={{2(n_{k}\pm g_{k})}\over{n_{k-1}+n_k\pm (g_{k-1}+g_k)}},
  430   &(10{\rm c})\cr
  431     }
  432   $$
  433   are the reflection and transmission coefficients at the interfaces, with primed
  434   coefficients relating to the backward travelling field components, and with all
  435   coefficients including linear magneto-optical effects.
  436   The reflection and transmission coefficients obey the Stokes relation
  437   $$
  438     \tau_{k_{\pm}}=(1-\rho^2_{k_{\pm}})/\tau'_{k_{\mp}},
  439   $$
  440   reflecting the polarization state dependence of the boundary conditions at the
  441   layer interfaces.
  442   This linear approximation of the boundary conditions can be assumed to hold
  443   whenever processes such as the optical Kerr-effect gives a contribution to the
  444   electric polarization density which is small compared to the one given by the
  445   linear polarizability of the medium, or equivalently whenever the nonlinear
  446   index of refraction is small compared to the linear one, which for a linearly
  447   polarized optical wave can be formulated as the condition
  448   $$
  449     (3/4)\chi^{\rm eeee}_{xxxx}\vert E^x_{\omega}\vert^2
  450     \ll 1+\chi^{\rm ee}_{xx}.
  451   $$
  452   
  453   @ Solving the equations of motion for the inverse problem of transmission.
  454   In order to solve Eqs.~(4) and~(9) for the relation between incident ($k=0$)
  455   and transmitted ($k=N$) fields, we impose the additional boundary condition
  456   that the backward propagating field is zero at the exit end of the grating.
  457   By iteratively using Eqs.~(9) and~(4) in the order $k=N-1,N-2,\ldots,1$,
  458   consecutively solving for lower-indexed electric fields, we obtain an
  459   algorithm for solving the inverse problem, calculating the incident and
  460   reflected optical fields corresponding to a transmitted optical field.
  461   This algorithm is explicitly described in Section~10, {\sl The algorithm of
  462   computation}.
  463   
  464   @ Interpretation of the solution in terms of the Stokes parameters.
  465   The evolution of the optical field is conveniently expressed in terms of the
  466   Stokes parameters~[5], which for the input light are taken as
  467   $$
  468     \eqalignno{
  469     S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
  470     S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],&(11{\rm a,b})\cr
  471     S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
  472     S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].&(11{\rm c,d})\cr
  473     }
  474   $$
  475   The parameter $S_0$ is a measure of the intensity of the wave, and $S_3$ a
  476   measure of the ellipticity of the polarization state, while the parameters
  477   $S_1$ and $S_2$ indicate the amount of power contained in the $x$- and
  478   $y$-directions, serving as to determine the orientation of the polarization
  479   ellipse. Similarly, the Stokes parameters for the transmitted light are taken
  480   as
  481   $$
  482     \eqalignno{
  483     W_0&=\vert E^{\rm f}_{N_+}\vert^2+\vert E^{\rm f}_{N_-}\vert^2,\qquad
  484     W_1=2\re[E^{{\rm f}*}_{N_+}E^{\rm f}_{N_-}],&(12{\rm a,b})\cr
  485     W_3&=\vert E^{\rm f}_{N_+}\vert^2-\vert E^{\rm f}_{N_-}\vert^2,\qquad
  486     W_2=2\im[E^{{\rm f}*}_{N_+}E^{\rm f}_{N_-}],&(12{\rm c,d})\cr
  487   }
  488   $$
  489   and for the reflected light
  490   $$
  491     \eqalignno{
  492     V_0&=\vert E^{\rm b}_{0_+}\vert^2+\vert E^{\rm b}_{0_-}\vert^2,\qquad
  493     V_1=2\re[E^{{\rm b}*}_{0_+}E^{\rm b}_{0_-}],&(13{\rm a,b})\cr
  494     V_3&=\vert E^{\rm b}_{0_+}\vert^2-\vert E^{\rm b}_{0_-}\vert^2,\qquad
  495     V_2=2\im[E^{{\rm b}*}_{0_+}E^{\rm b}_{0_-}].&(13{\rm c,d})\cr
  496   }
  497   $$
  498   In terms of $S_0$ and $W_0$, the incident, transmitted, and reflected
  499   intensities in \SI\ units are $I_{\rm in}=\varepsilon_0 c S_0/2$,
  500   $I_{\rm tr}=\varepsilon_0 c W_0/2$, and $I_{\rm re}=\varepsilon_0 c V_0/2$,
  501   respectively.
  502   These respective sets of Stokes parameters can be combined to form the reduced
  503   Stokes vectors
  504   $$
  505     {\bf s}=(S_1,S_2,S_3)/S_0,\qquad
  506     {\bf w}=(W_1,W_2,W_3)/W_0,\qquad
  507     {\bf v}=(V_1,V_2,V_3)/V_0,
  508   $$
  509   which map the polarization states of the respective incident, transmitted, and
  510   reflected light onto the unitary Poincar\'e sphere, with
  511   $\vert{\bf s}\vert=\vert{\bf w}\vert=\vert{\bf v}\vert=1$,
  512   as schematically illustrated in Fig.~2.
  513   \bigskip
  514   \centerline{\epsfxsize=122mm\epsfbox{figures/stoke/stoke.1}}\smallskip
  515   {\narrower\narrower\noindent{\bf Figure 2.} The unitary Poincar\'e sphere, on
  516   which the normalized Stokes vectors ${\bf s}=(S_1,S_2,S_3)/S_0$,
  517   ${\bf w}=(W_1,W_2,W_3)/W_0$, or ${\bf v}=(V_1,V_2,V_3)/V_0$ provide
  518   representations of the polarization state of the light. The auxiliary figures
  519   show the paths traversed by the end point of the electric field vector as the
  520   observer looks into an oncoming wave propagating in the positive $z$-direction.
  521   At the upper pole of the sphere the light is left circularly polarized (LCP),
  522   while it at the lower pole is right circularly polarized (RCP), with the
  523   latitude there in between determining the ellipticity of the polarization
  524   state.
  525   At the equator, linearly polarized states of the light are represented, and
  526   their orientations are determined by the meridian. The figure was adopted from
  527   Ref.~[9].\par}
  528   \bigskip
  529   \noindent
  530   The described algorithm of calculation as described by iteratively using
  531   Eqs.~(4)--(9) can be applied to a wide range of magneto-optical gratings,
  532   singly or multiply periodic, chirped, or even random without appreciable
  533   complication, by employing a spatial oversampling of the continuous grating
  534   profiles in terms of thin layers, so as to provide an efficient finite
  535   difference scheme of computation.
  536   Examples of computations performed on magneto-optical structures of continuous
  537   spatial distribution of the optical and magneto-optical parameters can be found
  538   in Refs.[6--8]
  539   
  540   @*The algorithm of computation. With the theory outlined we are now in position
  541   to explicitly describe the algorithm of computation of the transmission and
  542   reflection properties of the grating, as obtained by
  543   iteratively using Eqs.~(9) and~(4) in the order $k=N-1,N-2,\ldots,1$,
  544   consecutively solving for lower-indexed electric fields.
  545   This algorithm follows the one as described in Ref.~[2].
  546   
  547   \medskip
  548   \noindent{\bf Algorithm A}
  549   ({\it Calculation of amplitude reflection and transmission spectra}).
  550   The notation of geometry as used in the algorithm as here described refers to
  551   Fig.~1.
  552   Let ${E^{\rm f}_{N_{\pm}}(z_N)}$ be the complex-valued output optical
  553   field from the grating structure, as taken a coordinate $z=z^+_N$ immediately
  554   to the positive of the last interface $z_N$.
  555   The magneto-optical grating structure is described by the material
  556   parameters $n_k$, $g_k$, $p^{(k)}_{\pm}$, and
  557   $q^{(k)}_{\pm}$, which all are constant within each homogeneous
  558   layer $z_k\le z\le z_{k+1}$, $k=1,2,\ldots,N-1$.
  559   The optical fields in the respective homogeneous layers are denoted as
  560   ${E^{\rm f}_{k_{\pm}}(z)}$, for $z_k\le z\le z_{k+1}$, $k=1,2,\ldots,N-1$.
  561   
  562   \aitem[{\bf A1.}][Set boundary condition.]
  563     Apply the boundary condition $E^{\rm b}_{N_{\mp}}(z_N)=0$, that is to say,
  564     that the backward propagating field is zero after the end of the grating.
  565   
  566   \aitem[{\bf A2.}]{[Initialize forward field in layer $N-1$.]
  567     Using Eq.~(9a) for $k=N$ and furthermore applying the boundary condition in
  568     step A1 of the algorithm, set
  569     $$
  570       E^{\rm f}_{{N-1}_{\pm}}(z_N)\leftarrow
  571         [E^{\rm f}_{N_{\pm}}(z_N)/\tau_{{N}_{\pm}}]
  572           \exp[-i\omega n_{N-1}(z_N-z_{N-1})/c],
  573     $$
  574     where $\tau_{{N}_{\pm}}$ is the transmission coefficient as obtained from
  575     Eq.~(10b).
  576   }
  577   
  578   \aitem[{\bf A3.}]{[Initialize backward field in layer $N-1$.]
  579     Using Eq.~(9b) for $k=N-1$ and furthermore applying the boundary condition
  580     from A1 and the field calculated in A2, set
  581     $$
  582       E^{\rm b}_{{N-1}_{\mp}}(z_N)\leftarrow
  583         \rho_{{(N)}_{\pm}} E^{\rm f}_{{N-1}_{\pm}}(z_N)
  584           \exp[2i\omega n_{N-1}(z_N-z_{N-1})/c],
  585     $$
  586     where $\rho_{{(N)}_{\pm}}$ is the reflection coefficient as obtained from
  587     Eq.~(10a).
  588   }
  589   
  590   \aitem[{\bf A4.}]{[Initialize layer counter $k$.]
  591     Set $k\leftarrow N-1$. This is the counter which we use to keep track of
  592     the layers of the grating structure as this is traversed backwards, from the
  593     last layer $(k=N-1)$ towards the first one $(k=1)$.
  594   }
  595   
  596   \aitem[{\bf A5.}]{[Calculate propagation constants in the $k$th layer.]
  597     For a lossless medium the magnitudes of the circularly polarized field
  598     components are left invariant under propagation over a homogeneous layer,
  599     $$
  600       \vert E^{\rm f,b}_{k_{\pm}}(z_k)\vert
  601         =\vert E^{\rm f,b}_{k_{\pm}}(z_{k+1})\vert;
  602     $$
  603     and hence the field-dependent propagation constants $\eta^{\rm f}_{k_{\pm}}$
  604     and $\eta^{\rm b}_{k_{\pm}}$ of the layer $z^+_k\le z \le z^-_{k+1}$ are
  605     calculated using Eqs.~(5) as
  606     $$
  607       \eqalign{
  608         \eta^{\rm f}_{k_{\pm}}&\leftarrow
  609           p^{(k)}_{\pm}[\vert E^{\rm f}_{k_{\pm}}(z_{k+1})\vert^2
  610                            +2\vert E^{\rm b}_{k_{\mp}}(z_{k+1})\vert^2]
  611           +q^{(k)}_{\pm}[\vert E^{\rm f}_{k_{\mp}}(z_{k+1})\vert^2
  612                            +\vert E^{\rm b}_{k_{\pm}}(z_{k+1})\vert^2],\cr
  613         \eta^{\rm b}_{k_{\pm}}&\leftarrow
  614           p^{(k)}_{\mp}[\vert E^{\rm b}_{k_{\pm}}(z_{k+1})\vert^2
  615                            +2\vert E^{\rm f}_{k_{\mp}}(z_{k+1})\vert^2]
  616           +q^{(k)}_{\mp}[\vert E^{\rm b}_{k_{\mp}}(z_{k+1})\vert^2
  617                            +\vert E^{\rm f}_{k_{\pm}}(z_{k+1})\vert^2].\cr
  618       }
  619     $$
  620   }
  621   
  622   \aitem[{\bf A6.}]{[Propagate fields over the $k$th layer.]
  623     From the obtained complex-valued fields $E^{\rm f}_{k_{\pm}}(z_{k+1})$
  624     and $E^{\rm b}_{k_{\mp}}(z_{k+1})$, calculate the corresponding
  625     fields at the beginning $z=z^+_k$ of the $k$th layer by using Eqs.~(4),
  626     that is to say, set
  627     $$
  628       \eqalign{
  629         A^{\rm f}_{k_{\pm}}&\leftarrow
  630            \vert E^{\rm f}_{k_{\pm}}(z_{k+1})\vert,\cr
  631         A^{\rm b}_{k_{\pm}}&\leftarrow
  632            \vert E^{\rm b}_{k_{\pm}}(z_{k+1})\vert,\cr
  633         \psi^{\rm f}_{k_{\pm}}&\leftarrow
  634            \arg[E^{\rm f}_{k_{\pm}}(z_{k+1})]
  635            -\omega (\eta^{\rm f}_{k_{\pm}}\pm g_k)(z_{k+1}-z_k)/c,\cr
  636         \psi^{\rm b}_{k_{\pm}}&\leftarrow
  637            \arg[E^{\rm b}_{k_{\pm}}(z_{k+1})]
  638            +\omega (\eta^{\rm b}_{k_{\pm}}\mp g_k)(z_{k+1}-z_k)/c,\cr
  639       }
  640     $$
  641     and construct the fields $E^{\rm f}_{k_{\pm}}(z_k)$ and
  642     $E^{\rm b}_{k_{\pm}}(z_k)$ (taken immediately to the positive of $z_k$ in
  643     the $k$th layer) as
  644     $$
  645       \eqalign{
  646         E^{\rm f}_{k_{\pm}}(z_k)&\leftarrow
  647            A^{\rm f}_{k_{\pm}}\exp(i\psi^{\rm f}_{k_{\pm}}),\cr
  648         E^{\rm b}_{k_{\pm}}(z_k)&\leftarrow
  649            A^{\rm b}_{k_{\pm}}\exp(i\psi^{\rm b}_{k_{\pm}}).
  650       }
  651     $$
  652   }
  653   
  654   \aitem[{\bf A7.}]{[Check if the whole grating structure is traversed.]
  655     If the whole grating is traversed, that is to say if the layer counter has
  656     reached $k=1$, then proceed to A11; otherwise continue with A8.
  657   }
  658   
  659   \aitem[{\bf A8.}]{[Propagate forward traveling field components over interface
  660     located at $z=z_k$.]
  661     From the obtained complex-valued optical fields $E^{\rm f}_{k_{\pm}}(z_k)$
  662     and $E^{\rm b}_{k_{\mp}}(z_k)$, use Eq.~(9a) to calculate the corresponding
  663     forward propagating field at the negative side of the interface, at
  664     $z=z^-_k$, that is to say, set
  665     $$
  666       \eqalign{
  667         E^{\rm f}_{{k-1}_{\pm}}(z_k)&\leftarrow[E^{\rm f}_{k_{\pm}}(z_k)
  668           -\rho'_{{k}_{\mp}} E^{\rm b}_{k_{\mp}}(z_k)]
  669       \exp[-i \omega n_{k-1}(z_k-z_{k-1})/c]/\tau^{(k)}_{\pm}.
  670       }
  671     $$
  672   }
  673   
  674   \aitem[{\bf A9.}]{[Propagate backward traveling field components over interface
  675     located at $z=z_k$.]
  676     From the obtained complex-valued optical fields $E^{\rm f}_{k_{\pm}}(z_k)$
  677     and $E^{\rm b}_{k_{\mp}}(z_k)$, use Eq.~(9b) to calculate the corresponding
  678     backward propagating field at the negative side of the interface, at
  679     $z=z^-_k$, that is to say, set
  680     $$
  681       \eqalign{
  682         &E^{\rm b}_{{k-1}_{\mp}}(z_k)\leftarrow
  683         \tau^{(k)}_{\mp}{}' E^{\rm b}_{k_{\mp}}(z_k)
  684              \exp[i \omega n_{k-1}(z_k-z_{k-1})/c]
  685             +\rho^{(k)}_{\pm} E^{\rm f}_{{k-1}_{\pm}}(z_k)
  686              \exp[2i \omega n_{k-1}(z_k-z_{k-1})/c].
  687     }
  688   $$
  689   }
  690   
  691   \aitem[{\bf A10.}]{[Decrease layer counter.]
  692     Set $k\leftarrow k-1$ and return to A5.
  693   }
  694   
  695   \aitem[{\bf A11.}]{[Calculate input optical field.]
  696     From the obtained forward and backward propagating optical fields in the
  697     first ($k=1$) layer of the grating, calculate the corresponding input
  698     (forward propagating) field, that is to say, set
  699     $$
  700       E^{\rm f}_{0_{\pm}}(z_1)\leftarrow
  701         [E^{\rm f}_{1_{\pm}}(z_1)-\rho^{(1)}_{\mp}{}'E^{\rm b}_{1_{\mp}}(z_1)]
  702             /\tau^{(1)}_{\pm}.
  703     $$
  704   }
  705   
  706   \aitem[{\bf A12.}]{[Calculate reflected optical field.]
  707     From the obtained forward and backward propagating optical fields in the
  708     first ($k=1$) layer of the grating, and by using the calculated input optical
  709     field of A11, calculate the reflected optical field at the beginning of the
  710     grating, that is to say, set
  711     $$
  712       E^{\rm b}_{0_{\mp}}(z_1)\leftarrow
  713         \tau^{(1)}_{\mp}{}' E^{\rm b}_{1_{\mp}}(z_1)
  714           +\rho^{(1)}_{\pm} E^{\rm f}_{0_{\pm}}(z_1).
  715     $$
  716   }
  717   
  718   \aitem[{\bf A13.}]{[Calculate reflection and transmission coefficients.]
  719     Calculate any overall properties of the grating, such as the (intensity
  720     and polarization-state dependent) reflection and transmission
  721     $$
  722     \eqalign{
  723     R(\omega)&\leftarrow
  724       {{\vert E^{\rm b}_{0_+}(z_1)\vert^2+\vert E^{\rm b}_{0_-}(z_1)\vert^2}
  725       \over
  726       {\vert E^{\rm f}_{0_+}(z_1)\vert^2+\vert E^{\rm f}_{0_-}(z_1)\vert^2}},
  727   %\cr
  728   \qquad
  729     T(\omega)\leftarrow
  730       {{\vert E^{\rm f}_{N_+}(z_N)\vert^2+\vert E^{\rm f}_{N_-}(z_N)\vert^2}
  731       \over
  732       {\vert E^{\rm f}_{0_+}(z_1)\vert^2+\vert E^{\rm f}_{0_-}(z_1)\vert^2}},\cr
  733     }
  734     $$
  735     and terminate the algorithm.\quad\endalg}
  736   
  737   @*The Butcher and Cotter convention.
  738   As a ``recipe'' for the degeneracy factors in theoretical nonlinear optics,
  739   Butcher and Cotter~[10] provide a very useful convention which is well worth
  740   holding on to.
  741   For a superposition of monochromatic waves, and by invoking the general
  742   property of the intrinsic permutation symmetry, the monochromatic
  743   form of the $n$th order polarization density can be written as
  744   $$
  745     (P^{(n)}_{\omega_{\sigma}})_{\mu}
  746       =\varepsilon_0\sum_{\alpha_1}\cdots\sum_{\alpha_n}\sum_{\omega}
  747        K(-\omega_{\sigma};\omega_1,\ldots,\omega_n)
  748        \chi^{(n)}_{\mu\alpha_1\cdots\alpha_n}
  749        (-\omega_{\sigma};\omega_1,\ldots,\omega_n)
  750        (E_{\omega_1})_{\alpha_1}\cdots(E_{\omega_n})_{\alpha_n}.
  751     \eqno{(14)}
  752   $$
  753   The first summations in Eq.~(14), over $\alpha_1,\ldots,\alpha_n$,
  754   is simply an explicit way of stating that the Einstein convention
  755   of summation over repeated indices holds.
  756   The summation sign $\sum_{\omega}$, however, serves as a reminder
  757   that the expression that follows is to be summed over
  758   {\sl all distinct sets of $\omega_1,\ldots,\omega_n$}.
  759   Because of the intrinsic permutation symmetry, the frequency arguments
  760   appearing in Eq.~(14) may be written in arbitrary order.
  761   
  762   By ``all distinct sets of $\omega_1,\ldots,\omega_n$'', we here mean
  763   that the summation is to be performed, as for example in the case of
  764   optical Kerr-effect, over the single set of nonlinear susceptibilities
  765   that contribute to a certain angular frequency as
  766   $(-\omega;\omega,\omega,-\omega)$ {\sl or} $(-\omega;\omega,-\omega,\omega)$
  767   {\sl or} $(-\omega;-\omega,\omega,\omega)$.
  768   In this example, each of the combinations are considered as {\sl distinct},
  769   and it is left as an arbitary choice which one of these sets that are
  770   most convenient to use (this is simply a matter of choosing notation,
  771   and does not by any means change the description of the interaction).
  772   
  773   In Eq.~(14), the degeneracy factor $K$ is formally described as
  774   $$K(-\omega_{\sigma};\omega_1,\ldots,\omega_n)=2^{l+m-n}p$$
  775   where
  776   $$
  777     \eqalign{
  778       p&={\rm the\ number\ of\ {\sl distinct}\ permutations\ of}
  779          \ \omega_1,\omega_2,\ldots,\omega_1,\cr
  780       n&={\rm the\ order\ of\ the\ nonlinearity},\cr
  781       m&={\rm the\ number\ of\ angular\ frequencies}\ \omega_k
  782          \ {\rm that\ are\ zero,\ and}\cr
  783       l&=\bigg\lbrace\matrix{1,\qquad{\rm if}\ \omega_{\sigma}\ne 0,\cr
  784                              0,\qquad{\rm otherwise}.}\cr
  785     }
  786   $$
  787   In other words, $m$ is the number of DC electric fields present, and $l=0$ if
  788   the nonlinearity we are analyzing gives a static, or DC, polarization density,
  789   such as in the previously (in the spring model) described case of optical
  790   rectification in the presence of second harmonic fields (SHG).
  791   
  792   A list of frequently encountered nonlinear phenomena in nonlinear optics,
  793   including the degeneracy factors as conforming to the above convention, is
  794   given by Butcher and Cotter~[10], Table 2.1.
  795   
  796   @ Note on the complex representation of the optical field.
  797   Since the observable electric field of the light, in Butcher and
  798   Cotters notation taken as
  799   $$
  800     {\bf E}({\bf r},t)={{1}\over{2}}\sum_{\omega_k\ge 0}
  801     [{\bf E}_{\omega_k}\exp(-i\omega_k t)+{\bf E}^*_{\omega_k}\exp(i\omega_k t)],
  802   $$
  803   is a real-valued quantity, it follows that negative frequencies in the
  804   complex notation should be interpreted as the complex conjugate of the
  805   respective field component, or
  806   $$
  807     {\bf E}_{-\omega_k}={\bf E}^*_{\omega_k}.
  808   $$
  809   
  810   @ Example of degeneracy factor: The Optical Kerr-effect.
  811   Assume a monochromatic optical wave (containing forward and/or backward
  812   propagating components) polarized in the $xy$-plane,
  813   $$
  814     {\bf E}(z,t)=\re[{\bf E}_{\omega}(z)\exp(-i\omega t)]\in{\bf R}^3,
  815   $$
  816   with all spatial variation of the field contained in
  817   $$
  818     {\bf E}_{\omega}(z)={\bf e}_x E^x_{\omega}(z)
  819       +{\bf e}_y E^y_{\omega}(z)\in{\bf C}^3.
  820   $$
  821   Optical Kerr-effect is in isotropic media described by the third order
  822   susceptibility
  823   $$
  824     \chi^{(3)}_{\mu\alpha\beta\gamma}(-\omega;\omega,\omega,-\omega),
  825   $$
  826   with nonzero components of interest for the $xy$-polarized beam given in
  827   Appendix 3.3 of Butcher and Cotters book as
  828   $$
  829     \chi^{(3)}_{xxxx}=\chi^{(3)}_{yyyy},\quad
  830     \chi^{(3)}_{xxyy}=\chi^{(3)}_{yyxx}
  831     =\bigg\{\matrix{{\rm intr.\ perm.\ symm.}\cr
  832                (\alpha,\omega)\rightleftharpoons(\beta,\omega)\cr}\bigg\}=
  833     \chi^{(3)}_{xyxy}=\chi^{(3)}_{yxyx},\quad
  834     \chi^{(3)}_{xyyx}=\chi^{(3)}_{yxxy},
  835   $$
  836   with
  837   $$
  838     \chi^{(3)}_{xxxx}=\chi^{(3)}_{xxyy}+\chi^{(3)}_{xyxy}+\chi^{(3)}_{xyyx}.
  839   $$
  840   The degeneracy factor $K(-\omega;\omega,\omega,-\omega)$ is calculated as
  841   $$
  842     K(-\omega;\omega,\omega,-\omega)=2^{l+m-n}p=2^{1+0-3}3=3/4.
  843   $$
  844   From this set of nonzero susceptibilities, and using the calculated
  845   value of the degeneracy factor in the convention of Butcher and Cotter,
  846   we hence have the third order electric polarization density at
  847   $\omega_{\sigma}=\omega$ given as ${\bf P}^{(n)}({\bf r},t)=
  848   \re[{\bf P}^{(n)}_{\omega}\exp(-i\omega t)]$, with
  849   $$
  850     \eqalign{
  851       {\bf P}^{(3)}_{\omega}
  852       &=\sum_{\mu}{\bf e}_{\mu}(P^{(3)}_{\omega})_{\mu}\cr
  853       &=\{{\rm Using\ the\ convention\ of\ Butcher\ and\ Cotter}\}\cr
  854       &=\sum_{\mu}{\bf e}_{\mu}
  855         \bigg[\varepsilon_0{{3}\over{4}}\sum_{\alpha}\sum_{\beta}\sum_{\gamma}
  856          \chi^{(3)}_{\mu\alpha\beta\gamma}(-\omega;\omega,\omega,-\omega)
  857          (E_{\omega})_{\alpha}(E_{\omega})_{\beta}(E_{-\omega})_{\gamma}\bigg]\cr
  858       &=\{{\rm Evaluate\ the\ sums\ over\ } (x,y,z)
  859           {\rm\ for\ field\ polarized\ in\ the\ }xy{\rm\ plane}\}\cr
  860       &=\varepsilon_0{{3}\over{4}}\{
  861         {\bf e}_x[
  862           \chi^{(3)}_{xxxx} E^x_{\omega} E^x_{\omega} E^x_{-\omega}
  863           +\chi^{(3)}_{xyyx} E^y_{\omega} E^y_{\omega} E^x_{-\omega}
  864           +\chi^{(3)}_{xyxy} E^y_{\omega} E^x_{\omega} E^y_{-\omega}
  865           +\chi^{(3)}_{xxyy} E^x_{\omega} E^y_{\omega} E^y_{-\omega}]\cr
  866        &\qquad\quad
  867        +{\bf e}_y[
  868           \chi^{(3)}_{yyyy} E^y_{\omega} E^y_{\omega} E^y_{-\omega}
  869           +\chi^{(3)}_{yxxy} E^x_{\omega} E^x_{\omega} E^y_{-\omega}
  870           +\chi^{(3)}_{yxyx} E^x_{\omega} E^y_{\omega} E^x_{-\omega}
  871           +\chi^{(3)}_{yyxx} E^y_{\omega} E^x_{\omega} E^x_{-\omega}]\}\cr
  872       &=\{{\rm Make\ use\ of\ }{\bf E}_{-\omega}={\bf E}^*_{\omega}
  873           {\rm\ and\ relations\ }\chi^{(3)}_{xxyy}=\chi^{(3)}_{yyxx},
  874           {\rm\ etc.}\}\cr
  875       &=\varepsilon_0{{3}\over{4}}\{
  876         {\bf e}_x[
  877           \chi^{(3)}_{xxxx} E^x_{\omega} \vert E^x_{\omega}\vert^2
  878           +\chi^{(3)}_{xyyx} E^{y\,2}_{\omega} E^{x*}_{\omega}
  879           +\chi^{(3)}_{xyxy} \vert E^y_{\omega}\vert^2 E^x_{\omega}
  880           +\chi^{(3)}_{xxyy} E^x_{\omega} \vert E^y_{\omega}\vert^2]\cr
  881        &\qquad\quad
  882        +{\bf e}_y[
  883           \chi^{(3)}_{xxxx} E^y_{\omega} \vert E^y_{\omega}\vert^2
  884           +\chi^{(3)}_{xyyx} E^{x\,2}_{\omega} E^{y*}_{\omega}
  885           +\chi^{(3)}_{xyxy} \vert E^x_{\omega}\vert^2 E^y_{\omega}
  886           +\chi^{(3)}_{xxyy} E^y_{\omega} \vert E^x_{\omega}\vert^2]\}\cr
  887       &=\{{\rm Make\ use\ of\ intrinsic\ permutation\ symmetry}\}\cr
  888       &=\varepsilon_0{{3}\over{4}}\{
  889         {\bf e}_x[
  890           (\chi^{(3)}_{xxxx} \vert E^x_{\omega}\vert^2
  891             +2\chi^{(3)}_{xxyy} \vert E^y_{\omega}\vert^2) E^x_{\omega}
  892           +(\chi^{(3)}_{xxxx}-2\chi^{(3)}_{xxyy})
  893            E^{y\,2}_{\omega} E^{x*}_{\omega}\cr
  894        &\qquad\quad
  895         {\bf e}_y[
  896           (\chi^{(3)}_{xxxx} \vert E^y_{\omega}\vert^2
  897             +2\chi^{(3)}_{xxyy} \vert E^x_{\omega}\vert^2) E^y_{\omega}
  898           +(\chi^{(3)}_{xxxx}-2\chi^{(3)}_{xxyy})
  899            E^{x\,2}_{\omega} E^{y*}_{\omega}.\cr
  900     }
  901   $$
  902   For the optical field being linearly polarized, say in the $x$-direction,
  903   the expression for the polarization density is significantly simplified,
  904   to yield
  905   $$
  906     {\bf P}^{(3)}_{\omega}=\varepsilon_0(3/4){\bf e}_x
  907       \chi^{(3)}_{xxxx} \vert E^x_{\omega}\vert^2 E^x_{\omega},
  908   $$
  909   i.~e.~taking a form that can be interpreted as an intensity-dependent
  910   ($\sim\vert E^x_{\omega}\vert^2$) contribution to the refractive index
  911   (cf.~Butcher and Cotter \S 6.3.1).
  912   
  913   @*Rigorous theory of wave propagation in isotropic media.
  914   
  915   @ The tensor form of the electric polarizability.
  916   In the nonlinear susceptibility formalism, with the real-valued electric field
  917   and polarization density of the medium taken according to
  918   $$
  919     {\bf E}(z,t)=\re[{\bf E}_{\omega}\exp(-i\omega t)],\qquad
  920     {\bf P}(z,t)=\re[{\bf P}_{\omega}\exp(-i\omega t)]
  921   $$
  922   respectively, the complex-valued envelope for the polarization density is here
  923   given by the expression
  924   $$
  925     \eqalign{
  926     {\bf P}_{\omega}=&\varepsilon_0[
  927       {\bf e}_{\mu}\chi^{{\rm ee}}_{\mu\alpha}E^{\alpha}_{\omega}
  928       +{\bf e}_{\mu}\chi^{{\rm eem}}_{\mu\alpha\beta}
  929         E^{\alpha}_{\omega}B^{\beta}_0
  930       +{\bf e}_{\mu}K\chi^{{\rm eeee}}_{\mu\alpha\beta\gamma}
  931         E^{\alpha}_{\omega}E^{\beta}_{\omega}E^{\gamma*}_{\omega}
  932       +{\bf e}_{\mu}K\chi^{{\rm eeeem}}_{\mu\alpha\beta\gamma\delta}
  933         E^{\alpha}_{\omega}E^{\beta}_{\omega}E^{\gamma*}_{\omega}B^{\delta}_0],
  934   \cr
  935     }
  936   \eqno{(15)}
  937   $$
  938   in which the complex conjugated field components are to be associated with
  939   negative angular frequencies, as following from the reality condition
  940   ${\bf E}_{-\omega}={\bf E}^*_{\omega}$, and where $K=3/4$ is the degeneracy
  941   factor as explicitly included in the Butcher and Cotter convention of nonlinear
  942   optical susceptibilities~[10], as described in the previous section.
  943   For isotropic media, in particular then homogeneous layers of stacked gratings
  944   or elements of a discretized continuous-profile grating, the tensor elements
  945   involved in this expression are for arbitrary frequencies of the electric
  946   and magnetic fields listed in Table 1.
  947   \medskip
  948   \noindent{\bf Table 1.} Optical and magneto-optical susceptibilities of
  949   isotropic nonlinear magneto-optical media, for arbitrary angular frequency
  950   arguments of the tensors
  951   $\chi^{\rm ee}_{\alpha\beta}(-\omega_{\sigma};\omega_{\sigma})$,
  952   $\chi^{\rm eem}_{\alpha\beta\gamma}(-\omega_{\sigma};\omega_1,\omega_2)$,
  953   $\chi^{\rm eeee}_{\alpha\beta\gamma\delta}
  954   (-\omega_{\sigma};\omega_1,\omega_2,\omega_3)$, and
  955   $\chi^{\rm eeeem}_{\alpha\beta\gamma\delta\epsilon}
  956   (-\omega_{\sigma};\omega_1,\omega_2,\omega_3,\omega_4)$.
  957   In the table, $M$ denotes the number of nonzero elements while $N$ denotes
  958   the number of nonzero and independent elements.
  959   \smallskip
  960   \noindent{\hrule width 467pt}\vskip1pt
  961   \beginvrulealign
  962   \tabskip=0pt
  963   \halign{
  964     \hbox to 34pt{\hfil\vphantom{gP}#\hfil}% first column is centered
  965      &\hbox to 34pt{\hfil#\hfil}% second column is centered
  966      &\hbox to 28pt{\hfil#\hfil}% third column is centered
  967      &\hbox to 28pt{\hfil#\hfil}% fourth column is centered
  968      &\hbox to 343pt{\ \ #\hfil}\cr% fifth column is left aligned
  969     \noalign{{\hrule width 467pt}\vskip 2pt}
  970     Order&Source&$M$ & $N$ & Nonzero tensor elements\cr
  971     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
  972     1st &[1]&3&1&
  973     $\chi^{\rm ee}_{xx}=\chi^{\rm ee}_{yy}=\chi^{\rm ee}_{zz}$\cr
  974     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
  975     2nd &[1]&6&1&
  976     $\chi^{\rm eem}_{xyz}=\chi^{\rm eem}_{zxy}=\chi^{\rm eem}_{yzx}
  977       =-\chi^{\rm eem}_{xzy}=-\chi^{\rm eem}_{zyx}=-\chi^{\rm eem}_{yxz}$\cr
  978     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
  979     3rd &[2]&21&3&
  980     $\chi^{\rm eeee}_{xxxx}=\chi^{\rm eeee}_{yyyy}=\chi^{\rm eeee}_{zzzz}
  981       =\chi^{\rm eeee}_{xxyy}+\chi^{\rm eeee}_{xyxy}+\chi^{\rm eeee}_{xyyx}$,\cr
  982     &&&&
  983     $\chi^{\rm eeee}_{yyzz}=\chi^{\rm eeee}_{zzyy}=\chi^{\rm eeee}_{zzxx}
  984       =\chi^{\rm eeee}_{xxzz}=\chi^{\rm eeee}_{xxyy}=\chi^{\rm eeee}_{yyxx}$,\cr
  985     &&&&
  986     $\chi^{\rm eeee}_{yzyz}=\chi^{\rm eeee}_{zyzy}=\chi^{\rm eeee}_{zxzx}
  987       =\chi^{\rm eeee}_{xzxz}=\chi^{\rm eeee}_{xyxy}=\chi^{\rm eeee}_{yxyx}$,\cr
  988     &&&&
  989     $\chi^{\rm eeee}_{yzzy}=\chi^{\rm eeee}_{zyyz}=\chi^{\rm eeee}_{zxxz}
  990       =\chi^{\rm eeee}_{xzzx}=\chi^{\rm eeee}_{xyyx}=\chi^{\rm eeee}_{yxxy}$\cr
  991     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
  992     4th&[3]&60&6&
  993     $\chi^{\rm eeeem}_{xxxyz}
  994             =\chi^{\rm eeeem}_{yyyzx}
  995             =\chi^{\rm eeeem}_{zzzxy}
  996             = -\chi^{\rm eeeem}_{xxxzy}
  997             = -\chi^{\rm eeeem}_{yyyxz}
  998             = -\chi^{\rm eeeem}_{zzzyx}$\cr
  999     &&&&\qquad\quad\,\,\,\,\,
 1000             $= \chi^{\rm eeeem}_{xxyzx}
 1001                  +\chi^{\rm eeeem}_{xyxzx}
 1002                  +\chi^{\rm eeeem}_{yxxzx}$\cr
 1003     &&&&
 1004     $\chi^{\rm eeeem}_{xxyxz}
 1005             =\chi^{\rm eeeem}_{yyzyx}
 1006             =\chi^{\rm eeeem}_{zzxzy}
 1007             = -\chi^{\rm eeeem}_{xxzxy}
 1008             = -\chi^{\rm eeeem}_{yyxyz}
 1009             = -\chi^{\rm eeeem}_{zzyzx}$\cr
 1010       &&&&\qquad\quad\,\,\,\,\,
 1011             $= -\chi^{\rm eeeem}_{xxyzx}
 1012                  +\chi^{\rm eeeem}_{xyzxx}
 1013                  +\chi^{\rm eeeem}_{yxzxx}$\cr
 1014     &&&&
 1015     $\chi^{\rm eeeem}_{xyxxz}
 1016             =\chi^{\rm eeeem}_{yzyyx}
 1017             =\chi^{\rm eeeem}_{zxzzy}
 1018             = -\chi^{\rm eeeem}_{xzxxy}
 1019             = -\chi^{\rm eeeem}_{yxyyz}
 1020             = -\chi^{\rm eeeem}_{zyzzx}$\cr
 1021     &&&&\qquad\quad\,\,\,\,\,
 1022             $= -\chi^{\rm eeeem}_{xyxzx}
 1023                  -\chi^{\rm eeeem}_{xyzxx}
 1024                  +\chi^{\rm eeeem}_{yzxxx}$\cr
 1025     &&&&
 1026     $\chi^{\rm eeeem}_{yxxxz}
 1027             =\chi^{\rm eeeem}_{zyyyx}
 1028             =\chi^{\rm eeeem}_{xzzzy}
 1029             = -\chi^{\rm eeeem}_{zxxxy}
 1030             = -\chi^{\rm eeeem}_{xyyyz}
 1031             = -\chi^{\rm eeeem}_{yzzzx}$\cr
 1032     &&&&\qquad\quad\,\,\,\,\,
 1033             $= -\chi^{\rm eeeem}_{yxxzx}
 1034                  -\chi^{\rm eeeem}_{yxzxx}
 1035                  -\chi^{\rm eeeem}_{yzxxx}$\cr
 1036     &&&&
 1037     $\chi^{\rm eeeem}_{xxyzx}
 1038             =\chi^{\rm eeeem}_{yyzxy}
 1039             =\chi^{\rm eeeem}_{zzxyz}
 1040             = -\chi^{\rm eeeem}_{yyxzy}
 1041             = -\chi^{\rm eeeem}_{zzyxz}
 1042             = -\chi^{\rm eeeem}_{xxzyx}$\cr
 1043     &&&&
 1044     $\chi^{\rm eeeem}_{xyxzx}
 1045             =\chi^{\rm eeeem}_{yzyxy}
 1046             =\chi^{\rm eeeem}_{zxzyz}
 1047             = -\chi^{\rm eeeem}_{xzxyx}
 1048             = -\chi^{\rm eeeem}_{yxyzy}
 1049             = -\chi^{\rm eeeem}_{zyzxz}$\cr
 1050     &&&&
 1051     $\chi^{\rm eeeem}_{yxxzx}
 1052             =\chi^{\rm eeeem}_{zyyxy}
 1053             =\chi^{\rm eeeem}_{xzzyz}
 1054             = -\chi^{\rm eeeem}_{zxxyx}
 1055             = -\chi^{\rm eeeem}_{xyyzy}
 1056             = -\chi^{\rm eeeem}_{yzzxz}$\cr
 1057     &&&&
 1058     $\chi^{\rm eeeem}_{xyzxx}
 1059             =\chi^{\rm eeeem}_{yzxyy}
 1060             =\chi^{\rm eeeem}_{zxyzz}
 1061             = -\chi^{\rm eeeem}_{xzyxx}
 1062             = -\chi^{\rm eeeem}_{yxzyy}
 1063             = -\chi^{\rm eeeem}_{zyxzz}$\cr
 1064     &&&&
 1065     $\chi^{\rm eeeem}_{yxzxx}
 1066             =\chi^{\rm eeeem}_{zyxyy}
 1067             =\chi^{\rm eeeem}_{xzyzz}
 1068             = -\chi^{\rm eeeem}_{zxyxx}
 1069             = -\chi^{\rm eeeem}_{xyzyy}
 1070             = -\chi^{\rm eeeem}_{yzxzz}$\cr
 1071     &&&&
 1072     $\chi^{\rm eeeem}_{yzxxx}
 1073             =\chi^{\rm eeeem}_{zxyyy}
 1074             =\chi^{\rm eeeem}_{xyzzz}
 1075             = -\chi^{\rm eeeem}_{zyxxx}
 1076             = -\chi^{\rm eeeem}_{xzyyy}
 1077             = -\chi^{\rm eeeem}_{yxzzz}$\cr
 1078   }\endvrulealign
 1079   \vskip-9.55pt
 1080   {\hskip-.4pt\hrule width 467pt}\vskip 1pt
 1081   \noindent{\hskip-.2pt\hrule width 467pt}
 1082   \medskip
 1083   
 1084   \vfill\eject
 1085   
 1086   \medskip
 1087   \noindent{\bf Table 2.} Optical and magneto-optical susceptibilities of
 1088   isotropic nonlinear magneto-optical media, corresponding to those as listed
 1089   in Table~1, but for angular frequency arguments corresponding to the
 1090   particular choice of optical Kerr-effect and photo-induced Faraday rotation
 1091   in presence of a static magnetic field, % ${\bf B}_0$, with
 1092   $\chi^{\rm ee}_{\alpha\beta}(-\omega;\omega)$,
 1093   $\chi^{\rm eem}_{\alpha\beta\gamma}(-\omega;\omega,0)$,
 1094   $\chi^{\rm eeee}_{\alpha\beta\gamma\delta}
 1095   (-\omega;\omega,\omega,-\omega)$, and
 1096   $\chi^{\rm eeeem}_{\alpha\beta\gamma\delta\epsilon}
 1097   (-\omega;\omega,\omega,-\omega,0)$.
 1098   As in Table~1, $M$ denotes the number of nonzero elements while $N$ denotes
 1099   the number of nonzero and independent elements.
 1100   \smallskip
 1101   \noindent{\hrule width 467pt}\vskip1pt
 1102   \beginvrulealign
 1103   \tabskip=0pt
 1104   \halign{
 1105     \hbox to 34pt{\hfil\vphantom{gP}#\hfil}% first column is centered
 1106      &\hbox to 34pt{\hfil#\hfil}% second column is centered
 1107      &\hbox to 28pt{\hfil#\hfil}% third column is centered
 1108      &\hbox to 28pt{\hfil#\hfil}% fourth column is centered
 1109      &\hbox to 343pt{\ \ #\hfil}\cr% fifth column is left aligned
 1110     \noalign{{\hrule width 467pt}\vskip 2pt}
 1111     Order&Source&$M$ & $N$ & Nonzero tensor elements\cr
 1112     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
 1113     1st &[1]&3&1&
 1114     $\chi^{\rm ee}_{xx}=\chi^{\rm ee}_{yy}=\chi^{\rm ee}_{zz}$\cr
 1115     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
 1116     2nd &[1]&6&1&
 1117     $\chi^{\rm eem}_{xyz}=\chi^{\rm eem}_{zxy}=\chi^{\rm eem}_{yzx}
 1118       =-\chi^{\rm eem}_{xzy}=-\chi^{\rm eem}_{zyx}=-\chi^{\rm eem}_{yxz}$\cr
 1119     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
 1120     3rd &[2]&21&3&
 1121     $\chi^{\rm eeee}_{xxxx}=\chi^{\rm eeee}_{yyyy}=\chi^{\rm eeee}_{zzzz}
 1122       =\chi^{\rm eeee}_{xxyy}+\chi^{\rm eeee}_{xyxy}+\chi^{\rm eeee}_{xyyx}$,\cr
 1123     &&&&
 1124     $\chi^{\rm eeee}_{yyzz}=\chi^{\rm eeee}_{zzyy}=\chi^{\rm eeee}_{zzxx}
 1125       =\chi^{\rm eeee}_{xxzz}=\chi^{\rm eeee}_{xxyy}=\chi^{\rm eeee}_{yyxx}$,\cr
 1126     &&&&
 1127     $\chi^{\rm eeee}_{yzyz}=\chi^{\rm eeee}_{zyzy}=\chi^{\rm eeee}_{zxzx}
 1128       =\chi^{\rm eeee}_{xzxz}=\chi^{\rm eeee}_{xyxy}=\chi^{\rm eeee}_{yxyx}$,\cr
 1129     &&&&
 1130     $\chi^{\rm eeee}_{yzzy}=\chi^{\rm eeee}_{zyyz}=\chi^{\rm eeee}_{zxxz}
 1131       =\chi^{\rm eeee}_{xzzx}=\chi^{\rm eeee}_{xyyx}=\chi^{\rm eeee}_{yxxy}$\cr
 1132     \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
 1133     4th&[3]&60&6&
 1134     $\chi^{\rm eeeem}_{xxxyz}
 1135             =\chi^{\rm eeeem}_{yyyzx}
 1136             =\chi^{\rm eeeem}_{zzzxy}
 1137             = -\chi^{\rm eeeem}_{xxxzy}
 1138             = -\chi^{\rm eeeem}_{yyyxz}
 1139             = -\chi^{\rm eeeem}_{zzzyx}$\cr
 1140     &&&&\qquad\quad\,\,\,\,\,
 1141             $= \chi^{\rm eeeem}_{xxyzx}
 1142                  +\chi^{\rm eeeem}_{xyxzx}
 1143                  +\chi^{\rm eeeem}_{yxxzx}$\cr
 1144     &&&&
 1145     $\chi^{\rm eeeem}_{xxyxz}
 1146             =\chi^{\rm eeeem}_{yyzyx}
 1147             =\chi^{\rm eeeem}_{zzxzy}
 1148             = -\chi^{\rm eeeem}_{xxzxy}
 1149             = -\chi^{\rm eeeem}_{yyxyz}
 1150             = -\chi^{\rm eeeem}_{zzyzx}$\cr
 1151       &&&&\qquad\quad\,\,\,\,\,
 1152             $= -\chi^{\rm eeeem}_{xxyzx}
 1153                  +\chi^{\rm eeeem}_{xyzxx}
 1154                  +\chi^{\rm eeeem}_{yxzxx}$\cr
 1155     &&&&
 1156     $\chi^{\rm eeeem}_{xyxxz}
 1157             =\chi^{\rm eeeem}_{yzyyx}
 1158             =\chi^{\rm eeeem}_{zxzzy}
 1159             = -\chi^{\rm eeeem}_{xzxxy}
 1160             = -\chi^{\rm eeeem}_{yxyyz}
 1161             = -\chi^{\rm eeeem}_{zyzzx}$\cr
 1162     &&&&\qquad\quad\,\,\,\,\,
 1163             $= -\chi^{\rm eeeem}_{xyxzx}
 1164                  -\chi^{\rm eeeem}_{xyzxx}
 1165                  +\chi^{\rm eeeem}_{yzxxx}$\cr
 1166     &&&&
 1167     $\chi^{\rm eeeem}_{yxxxz}
 1168             =\chi^{\rm eeeem}_{zyyyx}
 1169             =\chi^{\rm eeeem}_{xzzzy}
 1170             = -\chi^{\rm eeeem}_{zxxxy}
 1171             = -\chi^{\rm eeeem}_{xyyyz}
 1172             = -\chi^{\rm eeeem}_{yzzzx}$\cr
 1173     &&&&\qquad\quad\,\,\,\,\,
 1174             $= -\chi^{\rm eeeem}_{yxxzx}
 1175                  -\chi^{\rm eeeem}_{yxzxx}
 1176                  -\chi^{\rm eeeem}_{yzxxx}$\cr
 1177     &&&&
 1178     $\chi^{\rm eeeem}_{xxyzx}
 1179             =\chi^{\rm eeeem}_{yyzxy}
 1180             =\chi^{\rm eeeem}_{zzxyz}
 1181             = -\chi^{\rm eeeem}_{yyxzy}
 1182             = -\chi^{\rm eeeem}_{zzyxz}
 1183             = -\chi^{\rm eeeem}_{xxzyx}$\cr
 1184     &&&&
 1185     $\chi^{\rm eeeem}_{xyxzx}
 1186             =\chi^{\rm eeeem}_{yzyxy}
 1187             =\chi^{\rm eeeem}_{zxzyz}
 1188             = -\chi^{\rm eeeem}_{xzxyx}
 1189             = -\chi^{\rm eeeem}_{yxyzy}
 1190             = -\chi^{\rm eeeem}_{zyzxz}$\cr
 1191     &&&&
 1192     $\chi^{\rm eeeem}_{yxxzx}
 1193             =\chi^{\rm eeeem}_{zyyxy}
 1194             =\chi^{\rm eeeem}_{xzzyz}
 1195             = -\chi^{\rm eeeem}_{zxxyx}
 1196             = -\chi^{\rm eeeem}_{xyyzy}
 1197             = -\chi^{\rm eeeem}_{yzzxz}$\cr
 1198     &&&&
 1199     $\chi^{\rm eeeem}_{xyzxx}
 1200             =\chi^{\rm eeeem}_{yzxyy}
 1201             =\chi^{\rm eeeem}_{zxyzz}
 1202             = -\chi^{\rm eeeem}_{xzyxx}
 1203             = -\chi^{\rm eeeem}_{yxzyy}
 1204             = -\chi^{\rm eeeem}_{zyxzz}$\cr
 1205     &&&&
 1206     $\chi^{\rm eeeem}_{yxzxx}
 1207             =\chi^{\rm eeeem}_{zyxyy}
 1208             =\chi^{\rm eeeem}_{xzyzz}
 1209             = -\chi^{\rm eeeem}_{zxyxx}
 1210             = -\chi^{\rm eeeem}_{xyzyy}
 1211             = -\chi^{\rm eeeem}_{yzxzz}$\cr
 1212     &&&&
 1213     $\chi^{\rm eeeem}_{yzxxx}
 1214             =\chi^{\rm eeeem}_{zxyyy}
 1215             =\chi^{\rm eeeem}_{xyzzz}
 1216             = -\chi^{\rm eeeem}_{zyxxx}
 1217             = -\chi^{\rm eeeem}_{xzyyy}
 1218             = -\chi^{\rm eeeem}_{yxzzz}$\cr
 1219   }\endvrulealign
 1220   \vskip-9.55pt
 1221   {\hskip-.4pt\hrule width 467pt}\vskip 1pt
 1222   \noindent{\hskip-.2pt\hrule width 467pt}
 1223   \medskip
 1224   
 1225   @ The vectorial form of the polarization density.
 1226   By expanding the tensorial form of the polarization denisty as given by
 1227   Eq.~(15) and using the nonzero elements of the susceptibility tensors as
 1228   given in Table~2, one after some straightforward algebra obtains the
 1229   polarization density of the medium in a vectorial form as
 1230   $$
 1231     \eqalign{
 1232     {\bf P}_{\omega}=&\varepsilon_0[\chi^{{\rm ee}}_{xx} {\bf E}_{\omega}
 1233       +\chi^{{\rm eem}}_{xyz} {\bf E}_{\omega}\times{\bf B}_0
 1234       +\threefourth
 1235         (\chi^{{\rm eeee}}_{xxxx}-\chi^{{\rm eeee}}_{xyyx})
 1236         ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}
 1237       +\threefourth\chi^{{\rm eeee}}_{xyyx}
 1238         ({\bf E}_{\omega}\cdot{\bf E}_{\omega}){\bf E}^*_{\omega}\cr
 1239      &+\threefourth\chi^{{\rm eeeem}}_{xyyyz}
 1240         ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}\times{\bf B}_0
 1241       +\threefourth\chi^{{\rm eeeem}}_{xxxyz}{\bf E}_{\omega}
 1242         ({\bf E}_{\omega}\cdot({\bf E}^*_{\omega}\times{\bf B}_0))],\cr
 1243     }
 1244   \eqno{(16)}
 1245   $$
 1246   where the degeneracy factor $K=3/4$ was explicitly stated with its numerical
 1247   value.
 1248   
 1249   @ The Polarization density in the Faraday configuration.
 1250   In the Faraday configuration~[1], the optical field propagates collinearly
 1251   with an externally applied static magnetic field ${\bf B}_0$.
 1252   Taking the direction of propagation as the $z$-axis in a Cartesian coordinate
 1253   system $({\bf e}_x,{\bf e}_y,{\bf e}_z)$ and furthermore assuming the infinite
 1254   plane wave approximation to hold for the transverse profile of the waves,
 1255   the probem of wave propagation becomes a one-dimensional nonlinear system.
 1256   
 1257   As a convention for circular polarization states, we employ the circularly
 1258   polarized basis vectors
 1259   $$
 1260     {\bf e}_{\pm}=({\bf e}_x\pm i{\bf e}_y)/\sqrt{2},
 1261   $$
 1262   which possesses the properties
 1263   $$
 1264     {\bf e}_{\pm}\times{\bf e}_z=\pm i{\bf e}_{\pm},\qquad
 1265     {\bf e}^*_{\pm}\cdot{\bf e}_{\pm}=1,\qquad
 1266     {\bf e}^*_{\pm}\cdot{\bf e}_{\mp}=0.
 1267   $$
 1268   In the circularly polarized basis, the fields are hence taken as ${\bf B}_0=
 1269   {\bf e}_z B^z_0$ and ${\bf E}_{\omega}={\bf e}_+ E^+_{\omega}+{\bf e}_-
 1270   E^-_{\omega}$, in which the electric field is the total one, including any
 1271   forward or backward traveling components. As this is inserted into Eq.~(2),
 1272   the electric polarization density of the medium hence becomes
 1273   $$
 1274     \eqalign{
 1275       {\bf e}^*_{\pm}\cdot{\bf P}_{\omega}&=
 1276         \varepsilon_0\{
 1277           (\chi^{\rm ee}_{xx}\pm i\chi^{\rm eem}_{xyz}B^z_0)E^{\pm}_{\omega}
 1278           +\threefourth[
 1279             (\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx})
 1280               \vert E^{\pm}_{\omega}\vert^2+
 1281             (\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx})
 1282               \vert E^{\mp}_{\omega}\vert^2]
 1283             E^{\pm}_{\omega}
 1284   \cr&\qquad
 1285        \pm\threefourth[
 1286             i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0
 1287               \vert E^{\pm}_{\omega}\vert^2+
 1288             i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0
 1289               \vert E^{\mp}_{\omega}\vert^2]
 1290             E^{\pm}_{\omega}
 1291         \}\cr
 1292     }
 1293   $$
 1294   From now on, the susceptibility tensor elements will for the sake of simplicity
 1295   in notation be incorporated into the index of refraction
 1296   $n=(1+\chi^{\rm ee}_{xx})^{1/2}$, the gyration coefficient
 1297   $\gamma=\chi^{\rm eem}_{xyz}B^z_0$, and the nonlinear optical and
 1298   magneto-optical parameters $p_{\pm}$ and $q_{\pm}$, defined as
 1299   $$
 1300     \eqalignno{
 1301       p_{\pm}&={{3}\over{8 n_{\pm}}}
 1302         [(\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx})
 1303           \pm i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0],
 1304         &(2{\rm a})\cr
 1305       q_{\pm}&={{3}\over{8 n_{\pm}}}
 1306         [(\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx})
 1307           \pm i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0],
 1308         &(2{\rm b})\cr
 1309     }
 1310   $$
 1311   where $n_{\pm}=(n^2\pm\gamma)^{1/2}$ are the effective refractive indices
 1312   for the circularly polarized components of the light,
 1313   to give the polarization density in Eq.~(1) in the simpler form
 1314   $$
 1315     {\bf e}^*_{\pm}\cdot{\bf P}_{\omega}=\varepsilon_0[n^2_{\pm}-1
 1316       +2n_{\pm}(p_{\pm}\vert E^{\pm}_{\omega}\vert^2
 1317         +q_{\pm}\vert E^{\mp}_{\omega}\vert^2)]E^{\pm}_{\omega}.
 1318     \eqno{(5)}
 1319   $$
 1320   The reason for includingthe refractive index in the particular scaling of the
 1321   nonlinear coefficients as apparing in $p_{\pm}$ and $q_{\pm}$ will become
 1322   obvious as the analysis proceeds with the wave equation.
 1323   As the polarization density given by Eq.~(5) is inserted into the wave
 1324   equation for the electric field inside the medium, one obtains the equation
 1325   of motion
 1326   $$
 1327     {{\partial^2 E^{\pm}_{\omega}}\over{\partial z^2}}
 1328     +{{\omega^2 n^2_{\pm}}\over{c^2}} E^{\pm}_{\omega}
 1329     +2n_{\pm}{{\omega^2}\over{c^2}}(p_{\pm}\vert E^{\pm}_{\omega}\vert^2
 1330         +q_{\pm}\vert E^{\mp}_{\omega}\vert^2)E^{\pm}_{\omega}=0.
 1331     \eqno{(5)}
 1332   $$
 1333   This equation determines the spatial evolution of the total electromagnetic
 1334   field, which may be composed of forward as well as backward traveling
 1335   components of arbitrary polarization state.
 1336   The task that now lies ahead is the separation of these components so as
 1337   to form a system which provides the basis for further analytical investigation.
 1338   
 1339   @ Separation into forward and traveling components.
 1340   It may from Eq.~(5) be noticed that in the absence of the nonlinear source
 1341   terms, the general solutions for the left and right circularly polarized
 1342   components of a forward traveling wave become
 1343   $$
 1344     E^+_{\omega}=E^{\rm f}_+\exp(in_+\omega z/c),\qquad
 1345     E^-_{\omega}=E^{\rm f}_-\exp(in_-\omega z/c),
 1346   $$
 1347   respectively,
 1348   where $E^{\rm f}_+$ and $E^{\rm f}_-$ are constants determined by the initial
 1349   conditions at some arbitrary point along the direction of propagation.
 1350   Meanwhile, the solution for the left/right circularly polarized components
 1351   of a backward traveling wave becomes
 1352   $$
 1353     E^+_{\omega}=E^{\rm b}_+\exp(in_-\omega z/c),\qquad
 1354     E^-_{\omega}=E^{\rm b}_-\exp(in_+\omega z/c),
 1355   $$
 1356   in which we here emphasize the change of effective refractive indices as
 1357   experienced compared to the forward traveling component.
 1358   This change is due to the fact that a backward traveling wave will experience
 1359   the applied static magnetic field as pointing in the opposite direction as
 1360   compared to the forward traveling wave, and hence the birefringence experienced
 1361   from the Faraday effect will be different in sign.
 1362   For a linearly polarized wave, this is manifested in that the polarization
 1363   state of the backward traveling wave will rotate in opposite direction around
 1364   the axis pointing in the direction of propagation, as compared to the forward
 1365   traveling wave.
 1366   Hence, by employing a separation according to
 1367   $$
 1368     \eqalign{
 1369     {\bf E}_{\omega}=
 1370       {\bf e}_+ &E^{\rm f}_+\exp(in_+\omega z/c)
 1371         +{\bf e}_- E^{\rm f}_-\exp(in_-\omega z/c)\cr
 1372        &+{\bf e}^*_+ E^{\rm b}_+\exp(-in_-\omega z/c)
 1373         +{\bf e}^*_- E^{\rm b}_-\exp(-in_+\omega z/c),\cr
 1374     }
 1375   \eqno{(6)}
 1376   $$
 1377   or equivalently in the scalar form
 1378   $$
 1379     E^{\pm}_{\omega}=E^{\rm f}_{\pm}\exp(i n_{\pm}\omega z/c)+
 1380       E^{\rm b}_{\mp}\exp(-in_{\pm}\omega z/c),
 1381   \eqno{(6)}
 1382   $$
 1383   the wave equation for the envelopes $E^{\rm f}_{\pm}$ and $E^{\rm b}_{\pm}$,
 1384   which generally are dependent on the coordinate $z$, naturally relaxes towards
 1385   the solution to the linear wave propagation problem, with $E^{\rm f}_{\pm}$
 1386   and $E^{\rm b}_{\pm}$ becoming constants whenever the nonlinear terms may be
 1387   neglected.
 1388   In addition, due to the separation of the linear phase evolution in this one
 1389   may also expect the field envelopes to be slowly varying functions of the
 1390   spatial coordinate $z$ under any reasonable nonlinear effects.
 1391   
 1392   By inserting Eq.~(6) into The polarization density given in Eq.~(5), the wave
 1393   equation (0) takes the form
 1394   $$
 1395     \eqalign{
 1396      \Big\{&{{\partial^2 E^{\rm f}_{\pm}}\over{\partial z^2}}
 1397         +2ik_{\pm}{{\partial E^{\rm f}_{\pm}}\over{\partial z}}
 1398         +2{{\omega^2 n_{\pm}}\over{c^2}}
 1399           [p_{\pm}(\vert E^{\rm f}_{\pm}\vert^2+2\vert E^{\rm b}_{\mp}\vert^2)
 1400             +q_{\pm}(\vert E^{\rm f}_{\mp}\vert^2+\vert E^{\rm b}_{\pm}\vert^2)]
 1401           E^{\rm f}_{\pm}
 1402       \Big\}\exp(ik_{\pm}z)\cr
 1403      &+\Big\{{{\partial^2 E^{\rm b}_{\mp}}\over{\partial z^2}}
 1404         -2ik_{\pm}{{\partial E^{\rm b}_{\mp}}\over{\partial z}}
 1405         +2{{\omega^2 n_{\pm}}\over{c^2}}
 1406           [p_{\pm}(\vert E^{\rm b}_{\mp}\vert^2+2\vert E^{\rm f}_{\pm}\vert^2)
 1407             +q_{\pm}(\vert E^{\rm b}_{\pm}\vert^2+\vert E^{\rm f}_{\mp}\vert^2)]
 1408           E^{\rm b}_{\mp}
 1409       \Big\}\exp(-ik_{\pm}z)\cr
 1410      &+2{{\omega^2 n_{\pm}}\over{c^2}}p_{\pm}
 1411         [E^{\rm f\,2}_{\pm}E^{\rm b*}_{\mp}\exp(3ik_{\pm}z)
 1412           +E^{\rm b\,2}_{\mp}E^{\rm f*}_{\pm}\exp(-3ik_{\pm}z)]\cr
 1413      &+2{{\omega^2 n_{\pm}}\over{c^2}}q_{\pm}
 1414         [E^{\rm f}_{\pm}E^{\rm f}_{\mp}E^{\rm b*}_{\pm}
 1415           \exp(i(k_{\pm}+2k_{\mp})z)
 1416          +E^{\rm b}_{\mp}E^{\rm b}_{\pm}E^{\rm f*}_{\mp}
 1417            \exp(-i(k_{\pm}+2k_{\mp})z)]\cr
 1418      &+2{{\omega^2 n_{\pm}}\over{c^2}}q_{\pm}
 1419         [E^{\rm f}_{\mp}E^{\rm b}_{\mp}E^{\rm b*}_{\pm}
 1420           \exp(i(2k_{\mp}-k_{\pm})z)
 1421          +E^{\rm b}_{\pm}E^{\rm f}_{\pm}E^{\rm f*}_{\mp}
 1422            \exp(-i(2k_{\mp}-k_{\pm})z)]=0,\cr
 1423     }
 1424   \eqno{(7)}
 1425   $$
 1426   where the notation $k_{\pm}\equiv\omega n_{\pm}/c$ was introduced for the
 1427   sake of algebraic simplicity.
 1428   In this equation, it may me noticed that the linear terms of the polarization
 1429   density have been eliminated, due to the particular choice of separation of
 1430   variables according to Eq.~(6).
 1431   However, in this form the wave propagation problem is extremely complex in its
 1432   analysis, and in order to proceed, two general approximations may be employed
 1433   without loosing much of generality. These are the slowly varying envelope
 1434   approximation and the method of projecting out spatially phase mismatched
 1435   terms.
 1436   The slowly varying envelope approximation simply assumes that the second-order
 1437   spatial derivative of the field envelope is much smaller in magnitude than
 1438   the first-order derivative multiplied by the wavevector, or in terms of the
 1439   here employed variables,
 1440   $$
 1441     \Big\vert{{\partial^2 E^{\rm f}_{\pm}}\over{\partial z^2}}\Big\vert\ll
 1442     2k_{\pm}\Big\vert{{\partial E^{\rm f}_{\pm}}\over{\partial z}}\Big\vert,
 1443   \qquad
 1444     \Big\vert{{\partial^2 E^{\rm b}_{\mp}}\over{\partial z^2}}\Big\vert\ll
 1445     2k_{\pm}\Big\vert{{\partial E^{\rm b}_{\mp}}\over{\partial z}}\Big\vert.
 1446   $$
 1447   By applying this approximation to Eq.~(7), one obtains the slightly simpler
 1448   system of equations
 1449   $$
 1450     \eqalign{
 1451      \Big\{&{{\partial E^{\rm f}_{\pm}}\over{\partial z}}
 1452         -i{{\omega}\over{c}}
 1453           [p_{\pm}(\vert E^{\rm f}_{\pm}\vert^2+2\vert E^{\rm b}_{\mp}\vert^2)
 1454             +q_{\pm}(\vert E^{\rm f}_{\mp}\vert^2+\vert E^{\rm b}_{\pm}\vert^2)]
 1455           E^{\rm f}_{\pm}
 1456       \Big\}\exp(ik_{\pm}z)\cr
 1457      &-\Big\{
 1458         {{\partial E^{\rm b}_{\mp}}\over{\partial z}}
 1459         +i{{\omega}\over{c}}
 1460           [p_{\pm}(\vert E^{\rm b}_{\mp}\vert^2+2\vert E^{\rm f}_{\pm}\vert^2)
 1461             +q_{\pm}(\vert E^{\rm b}_{\pm}\vert^2+\vert E^{\rm f}_{\mp}\vert^2)]
 1462           E^{\rm b}_{\mp}
 1463       \Big\}\exp(-ik_{\pm}z)\cr
 1464      &-i{{\omega}\over{c}}p_{\pm}
 1465         [E^{\rm f\,2}_{\pm}E^{\rm b*}_{\mp}\exp(3ik_{\pm}z)
 1466           +E^{\rm b\,2}_{\mp}E^{\rm f*}_{\pm}\exp(-3ik_{\pm}z)]\cr
 1467      &-i{{\omega}\over{c}}q_{\pm}
 1468         [E^{\rm f}_{\pm}E^{\rm f}_{\mp}E^{\rm b*}_{\pm}
 1469           \exp(i(k_{\pm}+2k_{\mp})z)
 1470          +E^{\rm b}_{\mp}E^{\rm b}_{\pm}E^{\rm f*}_{\mp}
 1471            \exp(-i(k_{\pm}+2k_{\mp})z)]\cr
 1472      &-i{{\omega}\over{c}}q_{\pm}
 1473         [E^{\rm f}_{\mp}E^{\rm b}_{\mp}E^{\rm b*}_{\pm}
 1474           \exp(i(2k_{\mp}-k_{\pm})z)
 1475          +E^{\rm b}_{\pm}E^{\rm f}_{\pm}E^{\rm f*}_{\mp}
 1476            \exp(-i(2k_{\mp}-k_{\pm})z)]=0.\cr
 1477     }
 1478   \eqno{(8)}
 1479   $$
 1480   Next step is now to project out terms which are closely phase matched, and in
 1481   particular then the terms related to the envelopes of the forward and backward
 1482   traveling components.
 1483   This is for the forward traveling parts done by multiplying Eq.~(8) by
 1484   $\exp(-ik_{\pm}z)$ and average the resulting equation over a few spatial
 1485   periods, assuming slowly varying field envelopes.
 1486   In performing this averaging, essentially two levels of approximation may be
 1487   applied: Either we keep also terms which are closely phase matched, that is
 1488   to say the term involving the exponent $\exp(i(2k_{\mp}-k_{\pm})z)$, or we
 1489   may assume that also this terms is averaged out for a sufficiently strong
 1490   Faraday effect.
 1491   This is in many cases a fully adequate approximation, in particular since
 1492   the main contribution to effects such as the ellipse rotation, optcal
 1493   Kerr-effect and photo-induced Faraday effect anyway are dominated by the
 1494   terms involving the absolute magnitude of the fields.
 1495   In the rigorous theory as here developed, however, these terms are kept for
 1496   the time being, so as to fully encounter for any effects introduced by these.
 1497   This method of projecting out the forward components is analogously applied
 1498   to the backward traveling ones, but for this case by instead multiplying the
 1499   equation by $\exp(ik_{\pm}z)$ prior to the averaging.
 1500   The resulting system of coupled equations for the envelopes of the forward
 1501   and backward traveling components of the field envelopes yield
 1502   $$
 1503     \eqalignno{
 1504       {{\partial E^{\rm f}_{\pm}}\over{\partial z}}
 1505         &=i{{\omega}\over{c}}\{
 1506            [p_{\pm}(\vert E^{\rm f}_{\pm}\vert^2+2\vert E^{\rm b}_{\mp}\vert^2)
 1507              +q_{\pm}(\vert E^{\rm f}_{\mp}\vert^2+\vert E^{\rm b}_{\pm}\vert^2)]
 1508            E^{\rm f}_{\pm}
 1509            +q_{\pm}E^{\rm f}_{\mp}E^{\rm b}_{\mp}E^{\rm b*}_{\pm}
 1510            \exp(\mp i\eta z)\}=0,&(9{\rm a})\cr
 1511       {{\partial E^{\rm b}_{\mp}}\over{\partial z}}
 1512         &=-i{{\omega}\over{c}}\{
 1513            [p_{\pm}(\vert E^{\rm b}_{\mp}\vert^2+2\vert E^{\rm f}_{\pm}\vert^2)
 1514              +q_{\pm}(\vert E^{\rm b}_{\pm}\vert^2+\vert E^{\rm f}_{\mp}\vert^2)]
 1515            E^{\rm b}_{\mp}
 1516            +q_{\pm}E^{\rm b}_{\pm}E^{\rm f}_{\pm}E^{\rm f*}_{\mp}
 1517            \exp(\pm i\eta z)\}=0,&(9{\rm b})\cr
 1518     }
 1519   $$
 1520   where the notation $\eta\equiv2(k_+-k_-)$ was introduced.
 1521   
 1522   
 1523   @ Separation of amplitude and phase of the field envelopes.
 1524   In order to proceed with Eqs.~(7), it is convenient to separate the wave
 1525   propagation into parts affecting the phase and amplitude of the forward and
 1526   backward traveling field envelopes.
 1527   In order to do so, the amplitude and phase of the field envelopes are taken
 1528   according to
 1529   $$
 1530     E^{\rm f,b}_{\pm}(z)=A^{\rm f,b}_{\pm}(z)\exp(i\psi^{\rm f,b}_{\pm}(z)),
 1531   $$
 1532   where $A^{\rm f,b}_{\pm}(z)\equiv\vert E^{\rm f,b}_{\pm}(z)\vert$ are the
 1533   amplitudes and $\psi^{\rm f,b}_{\pm}(z)$ the corresponding phases of
 1534   $E^{\rm f,b}_{\pm}(z)$.
 1535   This ansatz leads to Eqs.~(7) assuming the form
 1536   $$
 1537     \eqalignno{
 1538       \Big({{\partial A^{\rm f}_{\pm}}\over{\partial z}}
 1539         +iA^{\rm f}_{\pm}{{\partial\psi^{\rm f}_{\pm}}\over{\partial z}}\Big)
 1540       \exp(i\psi^{\rm f}_{\pm})
 1541         &=i{{\omega}\over{c}}\{
 1542            [p_{\pm}(A^{\rm f\,2}_{\pm}+2A^{\rm b\,2}_{\mp})
 1543              +q_{\pm}(A^{\rm f\,2}_{\mp}+A^{\rm b\,2}_{\pm})]
 1544            A^{\rm f}_{\pm}\exp(i\psi^{\rm f}_{\pm})
 1545   \cr&\hskip 50pt
 1546            +q_{\pm}A^{\rm f}_{\mp}A^{\rm b}_{\mp}A^{\rm b}_{\pm}
 1547            \exp(\mp i\eta z+i\psi^{\rm f}_{\mp}+i\psi^{\rm b}_{\mp}
 1548              -i\psi^{\rm b}_{\pm})\},&(11{\rm a})\cr
 1549       \Big({{\partial A^{\rm b}_{\mp}}\over{\partial z}}
 1550         +iA^{\rm b}_{\mp}{{\partial\psi^{\rm b}_{\mp}}\over{\partial z}}\Big)
 1551       \exp(i\psi^{\rm b}_{\mp})
 1552         &=-i{{\omega}\over{c}}\{
 1553            [p_{\pm}(A^{\rm b\,2}_{\mp}+2A^{\rm f\,2}_{\pm})
 1554              +q_{\pm}(A^{\rm b\,2}_{\pm}+A^{\rm f\,2}_{\mp})]
 1555            A^{\rm b}_{\mp}\exp(i\psi^{\rm b}_{\mp})
 1556   \cr&\hskip 50pt
 1557            +q_{\pm}A^{\rm b}_{\pm}A^{\rm f}_{\pm}A^{\rm f}_{\mp}
 1558            \exp(\pm i\eta z+i\psi^{\rm b}_{\pm}+i\psi^{\rm f}_{\pm}
 1559              -i\psi^{\rm f}_{\mp})\},&(11{\rm b})\cr
 1560     }
 1561   $$
 1562   or equivalently
 1563   $$
 1564     \eqalignno{
 1565       {{\partial A^{\rm f}_{\pm}}\over{\partial z}}
 1566         +iA^{\rm f}_{\pm}{{\partial\psi^{\rm f}_{\pm}}\over{\partial z}}
 1567         &=i{{\omega}\over{c}}\{
 1568            [p_{\pm}(A^{\rm f\,2}_{\pm}+2A^{\rm b\,2}_{\mp})
 1569              +q_{\pm}(A^{\rm f\,2}_{\mp}+A^{\rm b\,2}_{\pm})]A^{\rm f}_{\pm}
 1570            +q_{\pm}A^{\rm f}_{\mp}A^{\rm b}_{\mp}A^{\rm b}_{\pm}
 1571            \exp(\mp i\psi)\},&(12{\rm a})\cr
 1572       {{\partial A^{\rm b}_{\mp}}\over{\partial z}}
 1573         +iA^{\rm b}_{\mp}{{\partial\psi^{\rm b}_{\mp}}\over{\partial z}}
 1574         &=-i{{\omega}\over{c}}\{
 1575            [p_{\pm}(A^{\rm b\,2}_{\mp}+2A^{\rm f\,2}_{\pm})
 1576              +q_{\pm}(A^{\rm b\,2}_{\pm}+A^{\rm f\,2}_{\mp})]A^{\rm b}_{\mp}
 1577            +q_{\pm}A^{\rm b}_{\pm}A^{\rm f}_{\pm}A^{\rm f}_{\mp}
 1578            \exp(\pm i\psi)\},&(12{\rm b})\cr
 1579     }
 1580   $$
 1581   where the phase differences between the fields were incorporated into the
 1582   single variable $\psi=\psi(z)$, defined as
 1583   $$
 1584     \psi(z)\equiv\eta z+\psi^{\rm f}_+(z)-\psi^{\rm f}_-(z)
 1585       +\psi^{\rm b}_+(z)-\psi^{\rm b}_-(z).
 1586     \eqno{(13)}
 1587   $$
 1588   By multiplying Eqs.~(12) by respective amplitudes $A^{\rm f}_{\pm}$ and
 1589   $A^{\rm b}_{\mp}$, extracting the real parts of the left and right hand
 1590   sides of Eqs.~(12), and assumin a nonresonant medium in which $p_{\pm}$
 1591   and $q_{\pm}$ are real-valued quantities, one obtains the amplitude equations
 1592   $$
 1593     \eqalignno{
 1594       {{\partial A^{\rm f\,2}_{\pm}}\over{\partial z}}
 1595         =&\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
 1596           A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(14{\rm a})\cr
 1597       {{\partial A^{\rm b\,2}_{\mp}}\over{\partial z}}
 1598         =&\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
 1599           A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(14{\rm b})\cr
 1600     }
 1601   $$
 1602   while the analogous extraction of the imaginary parts instead provides the
 1603   phase equations
 1604   $$
 1605     \eqalignno{
 1606       A^{\rm f\,2}_{\pm}{{\partial\psi^{\rm f}_{\pm}}\over{\partial z}}
 1607         =&{{\omega}\over{c}}
 1608           [p_{\pm}(A^{\rm f\,2}_{\pm}+2A^{\rm b\,2}_{\mp})
 1609           +q_{\pm}(A^{\rm f\,2}_{\mp}+A^{\rm b\,2}_{\pm})]A^{\rm f\,2}_{\pm}
 1610           +{{\omega}\over{c}}q_{\pm}A^{\rm f}_+ A^{\rm f}_-
 1611             A^{\rm b}_+ A^{\rm b}_- \cos(\psi(z)),&(15{\rm a})\cr
 1612       A^{\rm b\,2}_{\mp}{{\partial\psi^{\rm b}_{\mp}}\over{\partial z}}
 1613         =&-{{\omega}\over{c}}
 1614           [p_{\pm}(A^{\rm b\,2}_{\mp}+2A^{\rm f\,2}_{\pm})
 1615           +q_{\pm}(A^{\rm b\,2}_{\pm}+A^{\rm f\,2}_{\mp})]A^{\rm b\,2}_{\mp}
 1616           -{{\omega}\over{c}}q_{\pm} A^{\rm f}_+ A^{\rm f}_-
 1617             A^{\rm b}_+ A^{\rm b}_- \cos(\psi(z)).&(15{\rm b})\cr
 1618     }
 1619   $$
 1620   The inclusion of the phases as differences into the single variable $\psi(z)$
 1621   is not, as one at a first glance might think, only just a matter of convenient
 1622   and compact notation.
 1623   In fact, by differentiating $\psi(z)$ with respect to $z$ and using the
 1624   phase evolution according to Eqs.~(10), it actually turns out that the
 1625   individual phases of the components of the optical wave can be eliminated
 1626   in favour of the single variable $\psi(z)$, hence providing an effective
 1627   reduction of the dimensionality of the problem, as will be shown in the
 1628   following sections.
 1629   
 1630   @ Invariants of motion.
 1631   As a short side track to the analysis, before proceeding with actually solving
 1632   the derived equations of motion for the amplitudes and phases of the field
 1633   components, we will now consider a few important points regarding conserved
 1634   quantities. These are important in the final stage when we separate out one
 1635   single differentail equation for one single field variable from the so far
 1636   complex and coupled system.
 1637   From the spatial evolution of the amplitudes as given in Eqs.~(14), one finds
 1638   that the magnitudes of the envelopes obey the invariants of motion
 1639   $$
 1640     {{\partial}\over{\partial z}}(A^{\rm f\,2}_+ - A^{\rm b\,2}_-)=0,\qquad
 1641     {{\partial}\over{\partial z}}(A^{\rm f\,2}_- - A^{\rm b\,2}_+)=0.
 1642   \eqno{(16)}
 1643   $$
 1644   Similarly, one also finds that the respective forward and backward traveling
 1645   circularly polarized components obey the invariants of motion
 1646   $$
 1647     {{\partial}\over{\partial z}}
 1648       (q_- A^{\rm f\,2}_+ + q_+ A^{\rm f\,2}_-)=0,\qquad
 1649     {{\partial}\over{\partial z}}
 1650       (q_+ A^{\rm b\,2}_+ + q_- A^{\rm b\,2}_-)=0.
 1651   \eqno{(17)}
 1652   $$
 1653   The invariants of motion given by Eqs.~(16) and~(17) can hence be summarized as
 1654   $$
 1655     \eqalignno{
 1656       A^{\rm f\,2}_+ - A^{\rm b\,2}_-&={\ \rm const.\ }
 1657         \equiv C_+/q_-,&(18{\rm a})\cr
 1658       A^{\rm f\,2}_- - A^{\rm b\,2}_+&={\ \rm const.\ }
 1659         \equiv C_-/q_+,&(18{\rm b})\cr
 1660       q_- A^{\rm f\,2}_+ + q_+ A^{\rm f\,2}_-&={\ \rm const.\ }\equiv 
 1661         I_{\rm f},&(18{\rm c})\cr
 1662       q_+ A^{\rm b\,2}_+ + q_- A^{\rm b\,2}_-&={\ \rm const.\ }\equiv 
 1663         I_{\rm b}.&(18{\rm d})\cr
 1664     }
 1665   $$
 1666   The reason for this particular choice of the form of the constants of motion,
 1667   with $C_+$ and $C_-$ scaled to be in units of $q_-$ and $q_+$, respectively,
 1668   is motivated later on by simplifying the notation when it comes to choosing
 1669   a normalized form for the equations of motion in the final stage of their
 1670   solving.
 1671   As Eqs.~(18) imply that the invariants of motion for the general, $z$-dependent
 1672   envelopes can be formulated as the linear algebraic system
 1673   $$
 1674     \pmatrix{
 1675       q_-&0&0&-q_-\cr
 1676       0&q_+&-q_+&0\cr
 1677       q_-&q_+&0&0\cr
 1678       0&0&q_+&q_-\cr
 1679     }
 1680     \pmatrix{A^{\rm f\,2}_+(z)\cr A^{\rm f\,2}_-(z)\cr
 1681       A^{\rm b\,2}_+(z)\cr A^{\rm b\,2}_-(z)\cr}
 1682     =\pmatrix{C_+\cr C_-\cr I_{\rm f}\cr I_{\rm b}\cr},
 1683     \eqno{(19)}
 1684   $$
 1685   one may be tempted to draw the conclusion that all envelopes
 1686   are constant with respect to the spatial coordinate~$z$.
 1687   However, this is a wrong conclusion, as one easily can verify that the
 1688   system~(18) is underdetermined, with a zero determinant of the system matrix,
 1689   as appearing in Eq.~(19).
 1690   
 1691   
 1692   @ Elimination of absolute phase dependence.
 1693   In order to reduce the algebraic complexity of Eqs.~(14) and~(15), which is
 1694   necessary in order proceed with the analytical theory of their evolution, we
 1695   will now eliminate the absolute phases of the fields in favour of the single
 1696   variable $\psi=\psi(z)$, which describes  the phase difference between the
 1697   four field components $E^{\rm f}_+$, $E^{\rm f}_-$, $E^{\rm b}_+$ and
 1698   $E^{\rm b}_-$.
 1699   This will reduce the dimension of of the problem from the original eight
 1700   variables present in Eqs.~(14) and~(15), down to a total of five coupled
 1701   variables and equations.
 1702   By differentiating the variable $\psi(z)$ with respect to $z$ and using
 1703   Eqs.~(10) one finds
 1704   $$
 1705     \eqalign{
 1706       {{\partial\psi}\over{\partial z}}
 1707       &=\eta
 1708         +{{\partial\psi^{\rm f}_+}\over{\partial z}}
 1709         -{{\partial\psi^{\rm f}_-}\over{\partial z}}
 1710         +{{\partial\psi^{\rm b}_+}\over{\partial z}}
 1711         -{{\partial\psi^{\rm b}_-}\over{\partial z}}\cr
 1712       &=\eta
 1713           +{{\omega}\over{c}}[p_+(A^{\rm f\,2}_++2A^{\rm b\,2}_-)
 1714           +q_+(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
 1715           +{{\omega}\over{c}}q_+
 1716           {{A^{\rm f}_- A^{\rm b}_- A^{\rm b}_+}\over{A^{\rm f}_+}}
 1717           \cos(\psi)
 1718         \cr&\qquad\qquad
 1719           -{{\omega}\over{c}}[p_-(A^{\rm f\,2}_-+2A^{\rm b\,2}_+)
 1720           +q_-(A^{\rm f\,2}_++A^{\rm b\,2}_-)]
 1721           -{{\omega}\over{c}}q_-
 1722           {{A^{\rm f}_+ A^{\rm b}_+ A^{\rm b}_-}\over{A^{\rm f}_-}}
 1723           \cos(\psi)
 1724         \cr&\qquad\qquad
 1725           -{{\omega}\over{c}}[p_-(A^{\rm b\,2}_++2A^{\rm f\,2}_-)
 1726           +q_-(A^{\rm b\,2}_-+A^{\rm f\,2}_+)]
 1727           -{{\omega}\over{c}}q_-
 1728           {{A^{\rm b}_- A^{\rm f}_- A^{\rm f}_+}\over{A^{\rm b}_+}}
 1729           \cos(\psi)
 1730         \cr&\qquad\qquad
 1731           +{{\omega}\over{c}}[p_+(A^{\rm b\,2}_-+2A^{\rm f\,2}_+)
 1732           +q_+(A^{\rm b\,2}_++A^{\rm f\,2}_-)]
 1733           +{{\omega}\over{c}}q_+
 1734           {{A^{\rm b}_+ A^{\rm f}_+ A^{\rm f}_-}\over{A^{\rm b}_-}}
 1735           \cos(\psi)\cr
 1736       &=\eta
 1737           +{{\omega}\over{c}}[3p_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1738             +2q_+(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
 1739           -{{\omega}\over{c}}[3p_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)
 1740             +2q_-(A^{\rm f\,2}_++A^{\rm b\,2}_-)]
 1741         \cr&\qquad\qquad
 1742           +{{\omega}\over{c}}\Big(
 1743             q_+ {{A^{\rm f}_- A^{\rm b}_- A^{\rm b}_+}\over{A^{\rm f}_+}}
 1744             -q_- {{A^{\rm f}_+ A^{\rm b}_+ A^{\rm b}_-}\over{A^{\rm f}_-}}
 1745             -q_- {{A^{\rm b}_- A^{\rm f}_- A^{\rm f}_+}\over{A^{\rm b}_+}}
 1746             +q_+ {{A^{\rm b}_+ A^{\rm f}_+ A^{\rm f}_-}\over{A^{\rm b}_-}}\Big)
 1747             \cos(\psi)\cr
 1748       &=\big\{{\rm\ Use\ Eqs.~(14)\ in\ substituting\ for\ terms\ in\ the\
 1749               second\ line\ }\big\}\cr
 1750       &=\eta
 1751           +{{\omega}\over{c}}[(3p_+-2q_-)(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1752             -(3p_--2q_+)(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
 1753         \cr&\qquad\qquad
 1754           +\Big(
 1755             {{1}\over{A^{\rm f}_+}}{{\partial A^{\rm f}_+}\over{\partial z}}
 1756             +{{1}\over{A^{\rm f}_-}}{{\partial A^{\rm f}_-}\over{\partial z}}
 1757             +{{1}\over{A^{\rm b}_+}}{{\partial A^{\rm b}_+}\over{\partial z}}
 1758             +{{1}\over{A^{\rm b}_-}}{{\partial A^{\rm b}_-}\over{\partial z}}
 1759           \Big){{\cos(\psi)}\over{\sin(\psi)}}\cr
 1760       &=\bigg\{{\rm\ Use\ }{{1}\over{A^{\rm f\,b}_{\pm}}}
 1761          {{\partial A^{\rm f,b}_{\pm}}\over{\partial z}}
 1762          ={{\partial}\over{\partial z}}\ln A^{\rm f,b}_{\pm}{\rm\ and\ }
 1763          \cos(\psi)/\sin(\psi)\equiv\cot(\psi)\bigg\}\cr
 1764       &=\eta
 1765           +{{\omega}\over{c}}[(3p_+-2q_-)(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1766             -(3p_--2q_+)(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
 1767         \cr&\qquad\qquad
 1768           +\Big(
 1769             {{\partial}\over{\partial z}}\ln A^{\rm f}_+
 1770             +{{\partial}\over{\partial z}}\ln A^{\rm f}_-
 1771             +{{\partial}\over{\partial z}}\ln A^{\rm b}_+
 1772             +{{\partial}\over{\partial z}}\ln A^{\rm b}_-
 1773           \Big)\cot(\psi)\cr
 1774       &=\eta
 1775           +{{\omega}\over{c}}[(3p_+-2q_-)(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1776             -(3p_--2q_+)(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
 1777           +\cot(\psi){{\partial}\over{\partial z}}
 1778             \ln(A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-).\cr
 1779     }
 1780   $$
 1781   Thus, by returning to the amplitude evolution described by Eqs.~(14) and by
 1782   defining the short-hand notation
 1783   $$
 1784     r_{\pm}\equiv(3p_{\pm}-2q_{\mp})
 1785   $$
 1786   for the coefficients of the nonlinear terms, the evolution of the optical
 1787   field can be summarized with the considerably simplified system of coupled
 1788   and nonlinear differential equations
 1789   $$
 1790     \eqalignno{
 1791       &{{\partial A^{\rm f\,2}_{\pm}}\over{\partial z}}
 1792          =\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
 1793           A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(19{\rm a})\cr
 1794       &{{\partial A^{\rm b\,2}_{\mp}}\over{\partial z}}
 1795          =\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
 1796           A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(19{\rm b})\cr
 1797       &{{\partial\psi}\over{\partial z}}
 1798          =\eta+({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1799             -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
 1800           +\cot(\psi){{\partial}\over{\partial z}}
 1801             \ln(A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-).&(19{\rm c})\cr
 1802     }
 1803   $$
 1804   Notice that the absolute phases of the field components now have been entirely
 1805   eliminated in favour of $\psi=\psi(z)$, as was the goal outset in the beginning
 1806   of this section.
 1807   The next step in the analysis is to eliminate also the relative phase from the
 1808   equations of motion, so as to provide an autonomous system only involving the
 1809   field amplitudes $A^{\rm f}_{\pm}$ and $A^{\rm b}_{\pm}$.
 1810   
 1811   @ Elimination of the relative phase.
 1812   The equations of motion given by Eqs.~(19) are considerably reduced in their
 1813   algebraic complexity as compared to the original ones, as given by Eqs.~(1).
 1814   However, there are still some simplifications which can be applied to further
 1815   reduce the complexity, in particular then the elimination of the phase
 1816   altogether, as will now be shown.
 1817   
 1818   The trick to apply is to first multiply the left and right hand sides of
 1819   Eq.~(19{\rm c}) with
 1820   $A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi)$, expanding the
 1821   spatial derivative on the right hand side, and rearrange the terms to obtain
 1822   $$
 1823     \eqalign{
 1824       &\cos(\psi){{\partial}\over{\partial z}}
 1825          (A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-)
 1826        -A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-
 1827          \sin(\psi){{\partial\psi}\over{\partial z}}
 1828   \cr&\qquad\qquad
 1829          =-\{\eta
 1830             +({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1831               -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]\}
 1832           A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi).\cr
 1833     }
 1834   \eqno{(20)}
 1835   $$
 1836   In this equation, we immediately find that the left hand side is the
 1837   spatial derivative of
 1838   $A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\cos(\psi)$, so we may start
 1839   looking for rewriting the right hand side as a spatial derivative as well,
 1840   in which case we would end up with an integrable equation.
 1841   In this search for a form of the right hand side which could be integrated,
 1842   the appearance of the factor $A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-
 1843   \sin(\psi)$ leads to using either of Eqs.~(19{\rm a}) or~(19{\rm b}) to
 1844   express this term as a derivative of the amplitudes instead, hopefully leading
 1845   to the right hand side as a polynomial form which is easily integrated.
 1846   Thus, Eq.~(20) can be rewritten as
 1847   $$
 1848     \eqalign{
 1849       {{\partial}\over{\partial z}}
 1850          (A^{\rm f}_+ &A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\cos(\psi))\cr
 1851       &=-\{\eta+({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1852             -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]\}
 1853           A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi).\cr
 1854       &=\big\{{\rm\ Use\ Eq.~(19a)\ in\ substituting\ for\ the\ factor\ }
 1855           A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi)\ \big\}\cr
 1856       &=-\{\eta+({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
 1857             -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]\}
 1858           {{1}\over{2({{\omega}/{c}})q_+}}
 1859             {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
 1860       &=\big\{{\rm\ Eliminate\ backward\ traveling\ components\ using\
 1861           Eqs.~(18a)\ and ~(18b)}\ \big\}\cr
 1862       &=-{{1}\over{q_+}}\Big\{{{\eta}\over{2({{\omega}/{c}})}}
 1863           +\onehalf
 1864           [r_+(2A^{\rm f\,2}_+-C_+/q_-)-r_-(2A^{\rm f\,2}_--C_-/q_+)]\Big\}
 1865           {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
 1866       &=\big\{{\rm\ Eliminate\ }A^{\rm f\,2}_-{\rm\ using\ Eq.~(18c)}\ \big\}\cr
 1867       &=-{{1}\over{q_+}}\Big\{{{\eta}\over{2({{\omega}/{c}})}}
 1868           +\onehalf
 1869           [r_+(2q_-A^{\rm f\,2}_+-C_+)/q_--r_-(2(I_{\rm f}-q_-A^{\rm f\,2}_+)
 1870           -C_-)/q_+]\Big\}
 1871           {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
 1872       &=\big\{{\rm\ Collect\ terms\ in\ powers\ of\ }A^{\rm f\,2}_+\ \big\}\cr
 1873       &=-{{1}\over{q_+}}\Big\{\Big(
 1874           {{\eta}\over{2({{\omega}/{c}})}}
 1875             -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
 1876           -{{r_-I_{\rm f}}\over{q_+}}\Big)
 1877           +{{(q_+r_++q_-r_-)}\over{q_+q_-}}q_-A^{\rm f\,2}_+
 1878         \Big\} {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
 1879       &=\big\{{\rm\ Identify\ as\ differential\ of\ polynomial\ of\ form\ }
 1880           p(A^{\rm f\,2}_+)\ \big\}\cr
 1881       &=-{{1}\over{q_+}}{{\partial}\over{\partial z}}\Big\{\Big(
 1882           {{\eta}\over{2({{\omega}/{c}})}}
 1883             -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
 1884           -{{r_-I_{\rm f}}\over{q_+}}\Big)A^{\rm f\,2}_+
 1885           +{{(q_+r_++q_-r_-)}\over{2q_+q_-}}q_-A^{\rm f\,4}_+
 1886         \Big\}\cr
 1887     }
 1888   \eqno{(21)}
 1889   $$
 1890   which directly integrates to yield
 1891   $$
 1892     \eqalign{
 1893       q_+ A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\cos(\psi)
 1894       &=\Gamma/q_--\Big[\Big(
 1895           {{\eta}\over{2({{\omega}/{c}})}}
 1896             -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
 1897           -{{r_-I_{\rm f}}\over{q_+}}\Big)A^{\rm f\,2}_+
 1898           +{{(q_+r_++q_-r_-)}\over{2q_+q_-}}q_-A^{\rm f\,4}_+
 1899         \Big]\cr
 1900       &=\Gamma/q_- -aA^{\rm f\,2}_+ - bq_-A^{\rm f\,4}_+,\cr
 1901     }
 1902   \eqno{(22)}
 1903   $$
 1904   where $\Gamma$ is a yet undetermined constant of integration, to be determined
 1905   later on by the boundary conditions of the homogeneous domain, and where the
 1906   short-hand notations
 1907   $$
 1908     a\equiv{{\eta}\over{2({{\omega}/{c}})}}
 1909       -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
 1910       -{{r_-I_{\rm f}}\over{q_+}},\qquad
 1911     b\equiv{{(q_+r_++q_-r_-)}\over{2q_+q_-}},
 1912   \eqno{(24)}
 1913   $$
 1914   were introduced.
 1915   The relative phase $\psi$ is now from Eq.~(22) determined in terms of the
 1916   field amplitudes, and in order to get an expression for the factor $\sin(\psi)$
 1917   which appears in the amplitude equations, for example in Eq.~(19a), we may
 1918   employ the trigonometric identity $\sin^2(\psi)+\cos^2(\psi)=1$, from which
 1919   we obtain Eq.~(19a) as
 1920   $$
 1921     \eqalign{
 1922       &{{\partial A^{\rm f\,2}_+}\over{\partial z}}=(-1)^k 2({{\omega}/{c}})
 1923       [q^2_+ A^{\rm f\,2}_+ A^{\rm f\,2}_- A^{\rm b\,2}_+ A^{\rm b\,2}_-
 1924       -(\Gamma/q_- -aA^{\rm f\,2}_+ - bq_-A^{\rm f\,4}_+)^2]^{1/2},\cr
 1925     }
 1926   \eqno{(23)}
 1927   $$
 1928   where the undeterminacy of the sign of $\sin(\psi)=\pm(1-\cos^2(\psi))^{1/2}$
 1929   is included in the factor $(-1)^k$, with~$k$ being a yet undetermined integer.
 1930   In this nonlinear differential equation, also the relative phase~$\psi$ is
 1931   eliminated, and the mathematical dimension of the problem at hand has been
 1932   reduced from in total eight variables to the present four ones given by the
 1933   linearly independent field amplitudes.
 1934   It may be observed that in deriving Eq.~(23), the invariants of motion given
 1935   by Eqs.~~(18) had to be employed, in order to be able to write the right-hand
 1936   side as a total derivative.
 1937   As the invariants of motion equally well still can be employed to further
 1938   reduce the dimensionality of the problem by eliminating $A^{\rm f\,2}_-$,
 1939   $A^{\rm b\,2}_+$ and $A^{\rm b\,2}_-$, we can at this stage easily see the
 1940   outline to finally formulate the problem of wave propagation as one single
 1941   differential equation involving only the single variable $A^{\rm f\,2}_+$.
 1942   
 1943   @ Elimination of redundant field amplitudes.
 1944   In this section, the dimensionality of the wave propagation problem is
 1945   finally reduced to yield a one-dimensional problem in one single variable
 1946   $A^{\rm f\,2}_+$.
 1947   By  eliminating the field amplitudes $A^{\rm f\,2}_-$,
 1948   $A^{\rm b\,2}_+$ and $A^{\rm b\,2}_-$ with the use of the
 1949   invariants of motion as given by Eqs.~(18), one obtains Eq.~(23) as
 1950   $$
 1951     \eqalign{
 1952       {{\partial A^{\rm f\,2}_+}\over{\partial z}}
 1953       &=(-1)^k 2({{\omega}/{c}})[q^2_+ A^{\rm f\,2}_+
 1954        \underbrace{{q^{-1}_+}(I_{\rm f}-q_- A^{\rm f\,2}_+)
 1955          }_{=A^{\rm f\,2}_-(z)}
 1956        \underbrace{{q^{-1}_+}(I_{\rm f}-q_- A^{\rm f\,2}_+ - C_-)
 1957          }_{=A^{\rm b\,2}_+(z)}
 1958        \underbrace{{q^{-1}_-}(q_-A^{\rm f\,2}_+ - C_+)
 1959          }_{=A^{\rm b\,2}_-(z)}
 1960   \cr&\hskip270pt
 1961       -{q^{-2}_-}(\Gamma -aq_-A^{\rm f\,2}_+ - bq^2_-A^{\rm f\,4}_+)^2]^{1/2}\cr
 1962       &=(-1)^k 2{{({{\omega}/{c}})}\over{q_-}}[q_-A^{\rm f\,2}_+
 1963        (I_{\rm f}-q_- A^{\rm f\,2}_+)
 1964        (I_{\rm f}-q_- A^{\rm f\,2}_+ - C_-)
 1965        (q_-A^{\rm f\,2}_+ - C_+)
 1966       -(\Gamma -aq_-A^{\rm f\,2}_+ - bq^2_-A^{\rm f\,4}_+)^2]^{1/2}.\cr
 1967     }
 1968   \eqno{(24)}
 1969   $$
 1970   Hence, by taking the normalized and dimensionless field amplitude variable
 1971   $v$ and the normalized and dimensionless coordinate $\zeta$ according to
 1972   $$
 1973     v\equiv q_-A^{\rm f\,2}_+,\qquad\zeta\equiv 2\omega z/c,\eqno{(25)}
 1974   $$
 1975   we obtain the normalized equation for the amplitude of the left circularly
 1976   polarized forward traveling field component as
 1977   $$
 1978     {{\partial v}\over{\partial\zeta}}=(-1)^k
 1979       [v(I_{\rm f}-v)(I_{\rm f}-v-C_-)(v-C_+)-(\Gamma-av-bv^2)^2]^{1/2}.
 1980   \eqno{(26)}
 1981   $$
 1982   This nonlinear ordinary differential equation is now well suited for numerical
 1983   evaluation, or even analytical as will be shown next. It should however be
 1984   noticed that the field amplitudes $A^{\rm f}_+$, $A^{\rm f}_-$, $A^{\rm b}_+$,
 1985   and $A^{\rm b}_-$ are all involved implicitly through the invariants of motion
 1986   $I_{\rm f}$, $C_+$, and $C_-$, as given by Eqs.~(18), and also via the
 1987   introduced short-hand notations $a$ and $b$ as introduced in Eq.~(24); also
 1988   the relative phase $\psi$ of the fields evaluated at some coordinate $\zeta_0$
 1989   enters as one parameter to encounter for, via the integration constant $\Gamma$
 1990   and Eq.~(22).
 1991   
 1992   
 1993   @ Formulation in terms of an elliptic integral.
 1994   The nonlinear ordinary differential equation~(26) for $v=v(\zeta)$ can be
 1995   formulated as
 1996   $$
 1997     {{\partial v}\over{\partial\zeta}}=(-1)^k[f(v)]^{1/2},\eqno{(27)}
 1998   $$
 1999   where
 2000   $$
 2001     f(v)\equiv a_4v^4+4a_3v^3+6a_2v^2+4a_1v+a_0
 2002   $$
 2003   is a quartic polynomial in the normalized field amplitudes $v$, and in which
 2004   the coefficients $a_j$, for $j=1,\ldots,4$, are explicitly given in terms of
 2005   the previously used algebraic symbols as
 2006   $$
 2007     \eqalignno{
 2008       a_0&=-\Gamma^2,&(28{\rm a})\cr
 2009       a_1&=(2\Gamma a-I^2_{\rm f}C_+ +I_{\rm f}C_+C_-)/4,&(28{\rm b})\cr
 2010       a_2&=(I^2_{\rm f}+2\Gamma b+2I_{\rm f}C_+-I_{\rm f}C_-
 2011               -a^2-C_+C_-)/6,&(28{\rm c})\cr
 2012       a_3&=(-2I_{\rm f}+C_- -C_--2ab)/4,&(28{\rm d})\cr
 2013       a_4&=1-b^2.&(28{\rm e})\cr
 2014     }
 2015   $$
 2016   The solution $v(\zeta)$ is then from Eq.~(27) given by the integral equation
 2017   $$
 2018     \int^{v(\zeta)}_{v(\zeta_0)}
 2019       {{dx}\over{(a_4x^4+4a_3x^3+6a_2x^2+4a_1x+a_0)^{1/2}}}
 2020       =(-1)^k\int^{\zeta}_{\zeta_0}\,d\zeta=(-1)^k(\zeta-\zeta_0),
 2021   \eqno{(29)}
 2022   $$
 2023   where $v_0\equiv v(\zeta_0)$ with $\zeta_0$ being an arbitrarily chosen
 2024   reference coordinate $\zeta_0$ along the axis of wave propagation.
 2025   
 2026   The left-hand side of Eq.~(29) constitutes an elliptic integral which
 2027   principally can be reduced to the Legendre-Jacobi normal form by means
 2028   of suitable homographic substitutions and the use of Jacobian elliptic
 2029   functions.
 2030   This implies the solving for the roots of the characteristic polynomial
 2031   equation $f(v)=0$ which, however perfectly well analytically solvable,
 2032   though is an algebraically very cumbersome task.
 2033   
 2034   A more convenient method is to instead employ notation and method of solution
 2035   by Weierstrass, which turns out to considerably simplify the algebra, and which
 2036   provides an analytic solution which can be computed analytically in terms of
 2037   the Weierstrass elliptic function~[11--13] $\wp(\zeta)=\wp(\zeta;g_2,g_3)$ with
 2038   the quartic invariants $g_2$ and $g_3$ as
 2039   $$
 2040     \eqalign{
 2041       g_2&\equiv a_0a_4-4a_1a_3+3a^2_2,
 2042   \qquad % &\cr
 2043       g_3\equiv
 2044       \left\vert\matrix{a_0&a_1&a_2\cr a_1&a_2&a_3\cr a_2&a_3&a_4\cr}\right\vert
 2045       =a_0a_2a_4+2a_1a_2a_3-a^3_2-a_0a^2_3-a^2_1a_4.\cr
 2046     }
 2047   $$
 2048   The solution $v(\zeta)$ of Eq.~(29) is then explicitly given as
 2049   $$
 2050     v(\zeta)=v_0+
 2051       {{\sqrt{f(v_0)}\wp'(\zeta)+{\textstyle{{1}\over{2}}}f'(v_0)
 2052       [\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]
 2053       +{\textstyle{{1}\over{24}}}f(v_0)f'''(v_0)}
 2054     \over{2[\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]^2
 2055       -{\textstyle{{1}\over{48}}}f(v_0)f^{\rm (iv)}(v_0)}}.
 2056   \eqno{(30)}
 2057   $$
 2058   That the solution given by Eq.~(30) actually {\sl is} a solution to the
 2059   differential equation~(27) can easily be verified using the MapleV code
 2060   \medskip
 2061   \leftskip=15mm
 2062   {\obeyspaces\obeylines\tt
 2063   restart:
 2064   f:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
 2065   +4*a[3]*v+a[4];
 2066   g[2]:=a[0]*a[4]-4*a[1]*a[3]+3*a[2]{\tothepower}2;
 2067   g[3]:=a[0]*a[2]*a[4]+2*a[1]*a[2]*a[3]-a[2]{\tothepower}3-a[0]*a[3]%
 2068   {\tothepower}2-a[1]{\tothepower}2*a[4];
 2069   df[0]:=eval(f,v=v0):
 2070   df[1]:=eval(diff(f,v{\dollar}1),v=v0):
 2071   df[2]:=eval(diff(f,v{\dollar}2),v=v0):
 2072   df[3]:=eval(diff(f,v{\dollar}3),v=v0):
 2073   df[4]:=eval(diff(f,v{\dollar}4),v=v0):
 2074   tmp[1]:=sqrt(df[0])*WeierstrassPPrime(z,g[2],g[3]):
 2075   tmp[2]:=(1/2)*df[1]*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]):
 2076   tmp[3]:=(1/24)*df[0]*df[3]:
 2077   tmp[4]:=2*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]){\tothepower}2:
 2078   tmp[5]:=(1/48)*df[0]*df[4]:
 2079   v:=v0+(tmp[1]+tmp[2]+tmp[3])/(tmp[4]-tmp[5]):
 2080   p:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
 2081   +4*a[3]*v+a[4]:
 2082   testfunc:=(diff(v,z)){\tothepower}2-p:
 2083   testfunc:=simplify(testfunc);\par}
 2084   \leftskip=0mm
 2085   \medskip
 2086   
 2087   @ Boundary conditions.
 2088   
 2089   @*Revision history of the program.
 2090   \medskip
 2091   
 2092   \citem[2002-10-28]{[v.1.0]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
 2093   First properly working version of the \magbragg\ program, written in plain
 2094   (\ANSI-conformant) \CEE.
 2095   
 2096   \citem[2002-11-15]{[v.1.1]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
 2097   Minor changes to the blocks of the program for the generation of reflection
 2098   spectra, providing data for a talk at the MRS 2002 Fall Meeting
 2099   [F.~Jonsson and C.~Flytzanis, {\sl Theoretical model for magneto-optical Bragg
 2100   gratings}, Talk O4.7 presented at the 2002 Materials Research
 2101   Society (MRS) Fall Meeting, Boston, United States (December 2--6, 2002)].
 2102   
 2103   \citem[2003-02-18]{[v.1.2]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
 2104   Modified the part of the program that writes the spatial optical field
 2105   distribution along the grating to file, so that both forward and backward
 2106   left and right circularly polarized components of the propagating fields are
 2107   written to file (using the \.{--fieldevolution} command line option).
 2108   
 2109   \citem[2003-02-25]{[v.1.3]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
 2110   Transferred all source code of the \magbragg\ program from \CEE\ to \CWEB.
 2111   For information on the \CWEB\ programming language, see
 2112   \.{http://www.literateprogramming.com}.
 2113   
 2114   \citem[2003-04-18]{[v.1.4]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
 2115   Added the \.{--modifylayer} option, enabling the user to manually modify
 2116   an arbitrary layer of the grating structure in linear as well as nonlinear
 2117   optical parameters, or modifying the layer thickness.
 2118   
 2119   \citem[2003-04-28]{[v.1.5]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
 2120   Added the \.{--intensityevolution} option.
 2121   
 2122   \citem[2003-07-15]{[v.1.6]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2123   Added some points in the documentation regarding the philosophy behind
 2124   creating two-dimensional plots from topological graphs of Stokes-parameter
 2125   hypersurfaces.
 2126   
 2127   \citem[2003-07-22]{[v.1.7]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2128   Added the possibility of specifiying whether the electrical field displacement
 2129   or Stokes parameters should be written to file, when saving the intra-grating
 2130   field distribution via the \.{--fieldevolution} command line option.
 2131   
 2132   \citem[2003-07-23]{[v.1.8]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2133   Changed the reference phase of the calculated, final intra-grating optical
 2134   field, so that the main axis of the polarization ellipse always is directed
 2135   along the $x$-axis (corresponding to $S_2=0$ in a Stokes parameter
 2136   description) at the beginning of the grating, at $z=0$.
 2137   (The naturally appearing reference phase is relative the output field, at the
 2138   end of the grating, since $z=L$ is the spatial starting point in the inverse
 2139   algorithm.)
 2140   
 2141   \citem[2003-08-04]{[v.1.9]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2142   Added the \.{--normalize\_length\_to\_um} option, which causes the program
 2143   to write spatial distances in micrometers instead of meters.
 2144   Useful for pre-normalizing data prior to importing it into programs
 2145   for making graphs of the spatial intra-grating distribution of intensity
 2146   or polarization state.
 2147   Also added the \.{--normalize\_intensity} option, which causes the program
 2148   to write the intensity-related Stoke parameter $S_0(z)$ as the quote
 2149   with the input intensity instead, as $S_0(z)/S_0(0)$.
 2150   
 2151   \citem[2003-08-07]{[v.1.10]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2152   Added the \.{--intensityspectrumfile} option, to save a regular intensity
 2153   spectrum as function of wavelength, and not only just the complex reflection
 2154   and transmission spectra.
 2155   Using this option, the character string following it will be used as the base
 2156   filename for the generated intensity reflection spectrum, which will be named
 2157   $\langle$basename$\rangle${\tt{.irsp.dat}}, and the intensity transmission
 2158   spectrum, which will be named $\langle$basename$\rangle${\tt{.itsp.dat}}.
 2159   The format of these files are simply that the first column is the vacuum
 2160   wavelength in nanometers, and the second column the reflection or transmission
 2161   coefficients.
 2162   In addition to these two files, an additional file
 2163   $\langle$basename$\rangle${\tt{.chec.dat}} will be generated, containing
 2164   the sum of the respective reflection and transmission coefficients.
 2165   Ideally, the second column of this file should be identically one;
 2166   any deviation from this is an artefact of the limited numerical precision
 2167   in the simulation, and can be taken as a measure on the correctness
 2168   of the obtained data.
 2169   
 2170   \citem[2003-08-19]{[v.1.11]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2171   Added the \.{--normalize\_ellipticity} option, which switch the program
 2172   to writing the normalized ellipticity $S_3/S_0$ (with a numerical value
 2173   between $-1$ and~$1$) instead of the third Stokes parameter, whenever it
 2174   is to be written to disk.
 2175   Also added the \.{--scale\_stokesparams} $\langle a\rangle$ option, which
 2176   at the stage of saving the Stokes parameters to disk divides the sets
 2177   $(S_0,S_1,S_2,S_3)$, $(W_0,W_1,W_2,W_3)$, and $(V_0,V_1,V_2,V_3)$ by the
 2178   scalefactor $\langle a\rangle$ prior to writing them to disk.
 2179   This is typically a good thing to do if the program that is to post-analyze
 2180   the generated data has a poor way of handling large numbers (typically larger
 2181   than $\sim 10^{14}$ for the squared amplitudes of the components of the
 2182   electric field).
 2183   
 2184   \citem[2003-08-20]{[v.1.12]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2185   Modified the \.{Makefile} to provide a somewhat more intelligent check on
 2186   which files that need to be updated on compilation. Also updated section five,
 2187   {\it Compiling the source code}, of the documentation of the program.
 2188   
 2189   \citem[2003-08-23]{[v.1.13]} \.{<hakkasberra@@hotmail.com>}\hfill\break
 2190   Added a check in the blocks that saves the full grating structure to file,
 2191   so that the program now fully recognizes the \.{--normalize\_length\_to\_um}
 2192   option.
 2193   
 2194   \citem[2003-10-06]{[v.1.14]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2195   Added a few clarifying paragraphs on the conventions used for the
 2196   magneto-optical material parameters and the exact conventions for the
 2197   circularly polarized modes as here used.
 2198   
 2199   \citem[2003-12-10]{[v.1.15]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2200   Added a few clarifying paragraphs on the scaling of the Stokes parameters
 2201   that are written to file after the finished calculations.
 2202   As a default, and as a matter of convention in electrodynamics in \SI\ units,
 2203   all Stokes parameters are given in ${\rm V}^2/{\rm m}^2$, through their
 2204   definition.
 2205   For example, the incident field (which is calculated by the program in
 2206   this inverse formulation of the problem) is expressed in terms of the Stokes
 2207   parameters as
 2208   $$
 2209   \eqalign{
 2210     S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
 2211     S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
 2212     S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
 2213     S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
 2214   }
 2215   $$
 2216   However, the direct interpretation of these quantities in terms of squared
 2217   Volts per square metres is sometimes somewhat inconvenient; therefore, those
 2218   parameters can be scaled to give an interpretation of the intensity (in regular
 2219   \SI\ units measured in Watts per square metres),
 2220   as $S'_k=(\varepsilon_0 c/2)S_k$, or explicitly
 2221   $$
 2222   \eqalign{
 2223     S'_0&=(\varepsilon_0 c/2)
 2224        [\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2],\qquad
 2225     S'_1=(\varepsilon_0 c/2)
 2226        2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
 2227     S'_3&=(\varepsilon_0 c/2)
 2228        [\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2],\qquad
 2229     S'_2=(\varepsilon_0 c/2)
 2230        2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
 2231   }
 2232   $$
 2233   In this representation, $S'_0$ is now identical to the incident intensity
 2234   $I_{\rm in}$ [${\rm W}/{\rm m}^2$].
 2235   In order to have those scaled Stokes parameters $S'_k$ written to file,
 2236   rather than the default ones, one convenient possibility is to use the
 2237   previously added \.{--scale\_stokesparams} option, to include
 2238   \.{--scale\_stokesparams 1.327209e-3} at the command line when invoking
 2239   the program. This numerical value of the scaling is obtained from
 2240   $$
 2241     \eqalign{
 2242       \varepsilon_0 c/2
 2243         &=(8.854187817\ldots\times 10^{-12}\ {\rm F}/{\rm m})
 2244           \times(2.99792458\times 10^8\ {\rm m}/{\rm s})/2\cr
 2245         &\approx 1.327209\times 10^{-3}\ {\rm F}/{\rm s}.\cr
 2246     }
 2247   $$
 2248   In regular \SI\ units as here used, the physical dimension of the
 2249   quantity $\varepsilon_0 c/2$ is $[({\rm A}\cdot{\rm s})/({\rm V}\cdot{\rm m})]
 2250   \cdot[{\rm m}/{\rm s}]=[{\rm A}/{\rm V}]$, so the physical dimension of
 2251   $(\varepsilon_0 c/2)S_k$ is hence $[{\rm A}/{\rm V}]\cdot[{\rm V}^2/{\rm m}^2]
 2252   =[{\rm W}/{\rm m}^2]$, as expected for an intensity measure (power per unit
 2253   area in the plane orthogonal to the direction of wave propagation).
 2254   
 2255   \citem[2003-12-10]{[v.1.16]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2256   Added the \.{--intensityinfo} option, in order to track down the maximum
 2257   optical intensity that is present inside (or outside) the magneto-optical
 2258   grating structure.
 2259   
 2260   \citem[2003-12-17]{[v.1.17]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2261   Added the \.{--trmtraject} option, in order to check the polarization
 2262   state evolution of the transmitted light for a varying incident intensity,
 2263   keeping the incident polarization state fixed.
 2264   Typically, we use two-dimensional interpolation to get the trajectory
 2265   of the transmitted polarization state as function of the incident light
 2266   (the incident light typically being of a fixed polarization state, with
 2267   a varying intensity). This trajectory can now be used as input to the
 2268   \magbragg\ program in the invserse formulation of the problem, for the
 2269   generation of Poincar\'e maps corresponding to cases with constant incident
 2270   polarization states and varying input intensity.
 2271   
 2272   \citem[2004-03-10]{[v.1.18]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2273   Last week in Stockholm I bought a new computer, a silvery Apple Macintosh
 2274   Powerbook~G4 running Apple \OSX\ (10.3 Panther). As I recompiled the
 2275   \CWEB\ source for the \magbragg\ program, still using the \GNU\ \CEE-compiler
 2276   (\GCC) for the executable file, I got complaints about the definition of the
 2277   \.{cabs} routine as shadowing a previously defined function.
 2278   This is a complaint that I never previously had with \GCC\ under \CYGWIN\ and
 2279   Windows 2000, and it is obvious that the \.{math.h} header file of \GCC\ has
 2280   been slightly changed lately.
 2281   However, after globally changing the routine name from \.{cabs} to
 2282   \.{cdabs} (which anyway is better since the new name also indicates that
 2283   it takes complex numbers in  {\sl double}\/ precision as input), there
 2284   were no more complaints, and the program now executes as expected in the
 2285   \OSX\ environment.
 2286   
 2287   \citem[2004-04-23]{[v.1.19]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2288   Fixed a bug in the initialization of chirped modulation of magneto-optical
 2289   parameters, for which the last $z$-coordinate of the discretized grating,
 2290   $z_N$, never was set.
 2291   
 2292   \citem[2004-04-24]{[v.1.20]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2293   Added the \.{--gyroperturb} option in order to provide a way of locally
 2294   manipulating and perturbing the gyration constant of the medium. This option
 2295   was added since I got this idea that a perturbation introduced by external
 2296   means, for example via a current carrying wire oriented orthogonally to the
 2297   direction of propagation of light in the Faraday configuration, could be used
 2298   for opening up a window in the transmission window of a chirped Bragg grating.
 2299   The syntax of the \.{--gyroperturb} option is simply \.{--gyroperturb}
 2300   $\langle z_{\rm p}\rangle$ $\langle a_{\rm p}\rangle$
 2301   $\langle w_{\rm p}\rangle$, where $\langle z_{\rm p}\rangle$ is the centre
 2302   position, $\langle a_{\rm p}\rangle$ is the zero-to-peak amplitude of change of
 2303   the gyration constant $g$, and $\langle w_{\rm p}\rangle$ is the corresponding
 2304   full width half maximum of the perturbation.
 2305   
 2306   \citem[2004-04-26]{[v.1.21]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
 2307   Added the \.{--stokesspectrum} option, so that it is possible to generate
 2308   full Poincar\'e maps of the spectral properties of a magneto-optical Bragg
 2309   grating. However, after having introduced this option, I get the following
 2310   message from \CWEAVE:
 2311   \citindent
 2312   {\obeyspaces\obeylines\tt
 2313   ~                   cweave magbragg
 2314   ~                   This is CWEAVE, Version 3.64 (Web2C 7.5.2)
 2315   ~                   *1*3*4*5*6*7*36*37*38*55*60*67*68*70
 2316   ~                   Writing the output file...*1*3*4*5*6*7*36*37*38*55*60
 2317   ~                   ! Sorry, scrap/token/text capacity exceeded. (l. 2912)
 2318   ~                      sprintf(outfilename\_w1,"\%s\%s",
 2319   ~                                                    outfilename,".w1.dat");
 2320   ~                   (That was a fatal error, my friend.)
 2321   ~                   make: *** [magbragg.tex] Error 1}
 2322   \medskip
 2323   \citindent
 2324   The \CEE\ code generated by \CTANGLE\ compiles and executes perfectly, but
 2325   obviously something is obstructing \CWEAVE\ to properly generating the
 2326   \TeX\ code for the documentation. Most annoying.
 2327   
 2328   \citem[2004-05-07]{[v.1.22]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
 2329   Added the \.{--displaysurrmedia}, which toggles if the program should write
 2330   also the surrounding media to saved grating profiles or not.
 2331   This is useful if one wish to just generate some part of a grating for a figure
 2332   illustrating a particular refractive index distribution, cut exactly to the
 2333   specified spatial interval of interest.
 2334   As default, the \magbragg\ program writes also the surrounding media to the
 2335   ends of the grating file, so by using this option only once at the command
 2336   line forces the program to cut the grating file exactly to the specified
 2337   spatial interval.
 2338   The annoying compilation error from 2004-04-26 is still present, preventing
 2339   me from generating the documentation.
 2340   
 2341   \citem[2004-07-03]{[v.1.23]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
 2342   I am in Germany for laboratory work in Wuppertal during two weeks, and this
 2343   free Saturday morning I decided to once and for all trace down and eliminate
 2344   the annoying parsing error that \CWEAVE\ produces.
 2345   (I am currently writing this entry at Starbucks in Cologne, being the only
 2346   caf\'e in town with a non-smoking policy $\ldots$)
 2347   Since this particular error seemed to stem from the block related to parsing
 2348   of the command line options, and since this block anyway by now has grown
 2349   over any reasonable size, I decided split it into several smaller blocks
 2350   instead. Having done so, \CWEAVE\ immediately accepted the \CWEB\ source
 2351   and extracted the \TeX\ source, which subsequently were compiled without
 2352   any errors. It thus seems like I on April 26th must have passed some upper
 2353   size limit on the source allowed in one single \CWEB\ block.
 2354   Not that I really expected such a built-in constraint in \CWEB, but in some
 2355   sense I can agree on that by putting some hard upper limit, one will at least
 2356   force the programmer to structure the code into smaller blocks, probably
 2357   increasing the readability.
 2358   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2359   \.{magbragg.w}) comprises 171418 bytes and 4138 lines of code.
 2360   The size of the compiled executable is 70340 bytes, and the PostScript
 2361   documentation is 808345 bytes (92 pages of A4 output in 10pt).
 2362   
 2363   \citem[2004-11-14]{[v.1.24]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
 2364   Added the \.{--apodize} option, to be able to get rid of some unwanted Gibbs
 2365   oscillations at the ends of the reflectance band of spectra generated for
 2366   chirped gratings, aimed to generate nice spectra for a talk to be presented at
 2367   the MRS 2004 Fall Meeting [F.~Jonsson and C.~Flytzanis, {\sl Artificially
 2368   Induced Perturbations in Chirped Magneto-Optical {Bragg} Gratings}, in
 2369   {\sl Magneto-Optical Materials for Photonics and Recording}, Eds.~{Koji Ando,
 2370   W. Challener, R. Gambino and M. Levy}, Mater. Res. Soc. Symp. Proc. {\bf 834},
 2371   J1.8 ({Materials Research Society}, {Warrendale}, 2005)].
 2372   Also added the \.{--phasejump} option (short form \.{-j}) to allow
 2373   specification of a discrete phase jump to appear in sinusoidal or chirped
 2374   grating structures.
 2375   In adding these options, the same error as of April 26th appeared again,
 2376   in the block related to the parsing of command line options.
 2377   Since this block has again grown over any reasonably readable size, I hence
 2378   started to split this block into smaller \CWEB\ sub-blocks, after which there
 2379   were no further complaints from \CWEAVE\ in extracting the \TeX\ documentation
 2380   of the program.
 2381   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2382   \.{magbragg.w}) comprises 179296 bytes and 4312 lines of code.
 2383   The size of the compiled executable is 74436 bytes, and the PostScript
 2384   documentation is 835671 bytes (95 pages of A4 output in 10pt).
 2385   
 2386   \citem[2004-12-04]{[v.1.25]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
 2387   Changed the way of output of Stokes parameters to file. Previously, the
 2388   program always opened files with extensions \.{.s0.dat},$\ldots$,
 2389   \.{.s3.dat} for output of the incident $S_k$ parameters (and similarly
 2390   for the reflected and transmitted Stokes parameters $V_k$ and $W_k$),
 2391   irregardless of the number of sampling points in intensity and ellipticity.
 2392   However, for sampling of spectral characteristics we most often only encounter
 2393   a simulation performed at one single intensity and ellipticity ($M_{\rm i}=1$
 2394   and $M_{\rm e}=1$), which means that, previously, twelve empty files were
 2395   opened and closed for each simulation. This is now changed so that the
 2396   program only opens those files for output in ``topological'' mode of
 2397   operation, in which $M_{\rm i}\ge2$ and $M_{\rm e}\ge2$. Compiling the
 2398   \CEE\ code with \GCC\ then caused some novel complaints using the
 2399   \.{--pedantic} option, regarding the risk of using the associated file
 2400   pointers uninitialized. That this complaint appear at all might be an
 2401   indicator that \GCC\ is not that strict in checking the logical state of
 2402   the program in which the file pointers were to be used, since I verified
 2403   that there was no reason whatsoever for the warnings.
 2404   The ``quick-and-dirty'' solution to get rid of the annoying and non-justified
 2405   warnings was to simply initialize all file pointers to \.{NULL} at the
 2406   beginning of the program.
 2407   Also started to write a separate section on all command line options currently
 2408   supported by \magbragg. The documentation has now for quite a while been in
 2409   urgent need of such a section, since the number of options have grown quite
 2410   a lot during the last year. As a start, the documentation for the
 2411   \.{--grating}, \.{--phasejump}, and \.{--apodize} options was updated.
 2412   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2413   \.{magbragg.w}) comprises 192945 bytes and 4611 lines of code.
 2414   The size of the compiled executable is 74436 bytes, and the PostScript
 2415   documentation is 873757 bytes (102 pages of A4 output in 10pt).
 2416   
 2417   \citem[2004-12-05]{[v.1.26]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
 2418   Added the feature that the program now uses \.{time.h} to extrapolate
 2419   what the estimated time of arrival (ETA) of the simulation is.
 2420   This is useful for predicting the total simulation time for large numbers of
 2421   sampled layers, such in long sinusoidal or chirped gratings. The estimation
 2422   is simply done via linear extrapolation as
 2423   $$
 2424     t_{\rm ETA}=t_0+{{t-t_0}\over{\{\%\,{\rm finished}\}}}\times100,
 2425   $$
 2426   to produce run-time messages of the form
 2427   \medskip
 2428   \leftskip=35mm
 2429   {\obeyspaces\obeylines\tt
 2430   Program execution started Sun Dec  5 20:55:27 2004
 2431   ----------------------------------------------------------------
 2432   ~...10 percent finished...    ETA: Sun Dec  5 21:44:57 2004
 2433   ~...20 percent finished...    ETA: Sun Dec  5 21:42:12 2004
 2434   ~...30 percent finished...    ETA: Sun Dec  5 21:41:17 2004
 2435   ~...40 percent finished...    ETA: Sun Dec  5 21:40:49 2004
 2436   ~...50 percent finished...    ETA: Sun Dec  5 21:40:33 2004
 2437   ~...60 percent finished...    ETA: Sun Dec  5 21:40:20 2004
 2438   ~...70 percent finished...    ETA: Sun Dec  5 21:40:12 2004
 2439   ~...80 percent finished...    ETA: Sun Dec  5 21:40:05 2004
 2440   ~...90 percent finished...    ETA: Sun Dec  5 21:40:01 2004
 2441   ~...done.           Elapsed execution time: 2644 s
 2442   ----------------------------------------------------------------
 2443   Program execution closed Sun Dec  5 21:39:31 2004\par}
 2444   \leftskip=0mm
 2445   \medskip
 2446   \citindent
 2447   Also wrote documentation on command-line specifications of chirped gratings,
 2448   and cleaned up the declarations of local variables somewhat.
 2449   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2450   \.{magbragg.w}) comprises 203691 bytes and 4830 lines of code.
 2451   The size of the compiled executable is 74532 bytes, and the PostScript
 2452   documentation is 898974 bytes (105 pages of A4 output in 10pt).
 2453   
 2454   \citem[2004-12-11]{[v.1.27]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
 2455   Added two schematic figures to the documentation on the discretization
 2456   of the grating.
 2457   
 2458   \citem[2005-04-22]{[v.1.28]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2459   Removed an unused block in the code for saving spectra to file, after having
 2460   thoroughly checked that it would have no affect on the backward compatibility
 2461   of the program to earlier data generated. Also increased the numerical
 2462   precision of the data written to file for the intensity reflection and
 2463   transmission spectra, which now yields \.{\%-10.8f} in floating point
 2464   conversion as conforming to \ANSICEE.
 2465   
 2466   \citem[2005-04-28]{[v.1.29]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2467   Added four blocks of text in the documentation of command line options.
 2468   
 2469   \citem[2005-06-08]{[v.1.30]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2470   In Stockholm for two months. Added the standard \CEE\ library function
 2471   |fflush()| for enforcement in writing of all buffered calculated data to file.
 2472   This in order to be able to follow the process of calculation more direct by
 2473   file inspection. When executing \magbragg\ under the new distribution of
 2474   \CYGWIN\ for Windows~XP, the block for the displaying of status of calculation
 2475   suddenly behaves odd, showing estimated execution times well below any
 2476   reasonable estimated time of arrival, and also going well beyond the maximum
 2477   100 percent in relative execution progress. This will have to be checked, and
 2478   has never previously appeared when compiling with \GCC, neither under Apple
 2479   \OSX (BSD), nor under \CYGWIN.
 2480   
 2481   \citem[2005-08-10]{[v.1.31]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2482   Back in Southampton again with my family after a hot summer. Wrote the code
 2483   for the |strip_away_path()| routine originally for the \poincare\ program and
 2484   immediately decided to adopt the code also into the \magbragg\ program in
 2485   order to finally solve the problem with long path strings that appear in
 2486   the program name string whenever poincare is called with an explicit path
 2487   specified at the command line. The call to the |strip_away_path()| routine
 2488   is located in the beginning of the block for command line parsing.
 2489   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2490   \.{magbragg.w}) comprises 219666 bytes and 5172 lines of code.
 2491   The size of the compiled (\CYGWIN) executable is 96647 bytes, and the
 2492   PostScript documentation is 967813 bytes (112 pages of A4 output in 10pt).
 2493   
 2494   \citem[2005-08-11]{[v.1.32]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2495   Cleaned up the blocks for displaying on-screen help messages. Wrote two
 2496   routines |hl()| and |fhl()| to assist a coherent style in displaying help on
 2497   command-line options.
 2498   
 2499   \citem[2005-08-19]{[v.1.33]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2500   Fixed two remaining bugs in the |hl()| and |fhl()|, in which \GCC\ under \OSX\
 2501   this evening complained that long unsigned integers were sent to standard
 2502   terminal output using the regular integer conversion of standard \CEE.
 2503   This warning did not show as the code was compiled with \GCC\ under \CYGWIN,
 2504   hence there seem to be some discrepancy between different ports of the
 2505   otherwise reliable compilator.
 2506   
 2507   \citem[2005-09-15]{[v.1.34]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2508   Corrected an error in the documentation of the options concerning
 2509   specifications of chirped sinusoidal grating structures. The chirp parameter
 2510   is now properly defined and described by example.
 2511   
 2512   \citem[2005-12-31]{[v.1.35]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2513   The theoretical description of the algorithm behind the solving of the inverse
 2514   problem in the \magbragg\ program is included in an article which today has
 2515   been accepted for publication in Physical Review Letters.
 2516   Added a section on the theoretical basis for the algorithm behind the program,
 2517   deriving the algorithm from the electromagnetic wave equation in a manner
 2518   similar to the description which soon will appear in the published article.
 2519   
 2520   \citem[2006-01-22]{[v.1.36]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2521   Added a section on the Butcher and Cotter convention of degeneracy factors in
 2522   nonlinear optics, picked from my {\sl Lecture Notes on Nonlinear Optics} from
 2523   the course I gave at the Royal Institute of Technology in 2003. Also edited the
 2524   section on the theoretical basis for the algorithm of calculation and added a
 2525   figure describing the representation of the polarization state on the
 2526   Poincar\'e sphere.
 2527   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2528   \.{magbragg.w}) comprises 252108 bytes and 5937 lines of code.
 2529   The size of the compiled (\OSX) executable is 78808 bytes, and the
 2530   PostScript documentation is 1651977 bytes (122 pages of A4 output in 10pt).
 2531   
 2532   \citem[2006-01-24]{[v.1.37]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2533   Added a significant number of comments on the use of variables and their
 2534   initialization. Also cleaned up and added more instructive text on the actual
 2535   compilation of the \CWEB\ source code.
 2536   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2537   \.{magbragg.w}) comprises 261933 bytes and 6086 lines of code.
 2538   The size of the compiled (\OSX) executable is 78828 bytes, and the
 2539   PostScript documentation is 1673601 bytes (125 pages of A4 output in 10pt).
 2540   
 2541   \citem[2006-02-09]{[v.1.38]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2542   As I now for a longer time of period have sketched on implementing the exact
 2543   methodology of solution for the waves inside the homogeneous elements of the
 2544   discretized medium, I today added the first sections on the theoretical part
 2545   of a rigorous theory of wave propagation.
 2546   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2547   \.{magbragg.w}) comprises 305905 bytes and 7095 lines of code.
 2548   The size of the compiled (\OSX) executable is 88002 bytes, and the
 2549   PostScript documentation is 1778021 bytes (135 pages of A4 output in 10pt).
 2550   
 2551   \citem[2006-02-11]{[v.1.39]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2552   Added two sections on how the amplitude evolution in the rigorous theory
 2553   of wave propagation actually can be reduced to the evaluation of an elliptic
 2554   function of the standard form
 2555   $$
 2556     \int^{v(\zeta)}_{v(\zeta_0)}{{dv}
 2557       \over{({a_4v^4+a_3v^3+a_2v^2+a_1v+a_0})^{1/2}}},
 2558   $$
 2559   with its solution $v(z)$ expressed in terms of the Weierstrass elliptic
 2560   function $\wp(\zeta;g_2,g_3)$ with the invariants $g_2$ and $g_3$
 2561   explicitly expressed in terms of $a_0$, $a_1$, $a_2$, $a_3$, and $a_4$.
 2562   
 2563   \citem[2006-03-13]{[v.1.40]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2564   After having spent some considerable time trying to verify that the integral
 2565   equation
 2566   $$
 2567     \int^{v(\zeta)}_{v(\zeta_0)}{{dv}
 2568       \over{({a_4v^4+4a_3v^3+6a_2v^2+4a_1v+a_0})^{1/2}}},
 2569   $$
 2570   which naturally appear in the rigorous theory of cross-phase modulation in
 2571   nonlinear magneto-optical media, really has the explicit solution
 2572   $$
 2573     v(\zeta)=v_0+
 2574       {{\sqrt{f(v_0)}\wp'(\zeta)+{\textstyle{{1}\over{2}}}f'(v_0)
 2575       [\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]
 2576       +{\textstyle{{1}\over{24}}}f(v_0)f'''(v_0)}
 2577     \over{2[\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]^2
 2578       -{\textstyle{{1}\over{48}}}f(v_0)f^{\rm (iv)}(v_0)}}.
 2579   $$
 2580   with quartic invariants
 2581   $$
 2582       g_2\equiv a_0a_4-4a_1a_3+3a^2_2,\qquad
 2583       g_3\equiv
 2584       \left\vert\matrix{a_0&a_1&a_2\cr a_1&a_2&a_3\cr a_2&a_3&a_4\cr}\right\vert
 2585       =a_0a_2a_4+2a_1a_2a_3-a^3_2-a_0a^2_3-a^2_1a_4,
 2586   $$
 2587   I today realized that the first edition of E.~T. Whittaker's {\sl A Course of
 2588   Modern Analysis} (Cambridge University Press, Cambridge, 1902) actually has
 2589   a printing error in one of the terms in the denominator of the solution.
 2590   This error has obviously been fixed in later editions of the book, for example
 2591   in E.~T.~Whittaker and G.~N.~Watson, {\sl A Course of Modern Analysis}, 4th
 2592   Reprinted Edn. (Cambridge University Press, Cambridge, 1996), ISBN
 2593   0-521-58807-3, but it caused be a considerable nuisance before I was able to
 2594   track the error down. The verification of the solution was checked using the
 2595   following blocks of MapleV code:
 2596   \medskip
 2597   \leftskip=30mm
 2598   {\obeyspaces\obeylines\tt
 2599   restart:
 2600   f:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
 2601   +4*a[3]*v+a[4];
 2602   g[2]:=a[0]*a[4]-4*a[1]*a[3]+3*a[2]{\tothepower}2;
 2603   g[3]:=a[0]*a[2]*a[4]+2*a[1]*a[2]*a[3]-a[2]{\tothepower}3-a[0]*a[3]%
 2604   {\tothepower}2-a[1]{\tothepower}2*a[4];
 2605   df[0]:=eval(f,v=v0):
 2606   df[1]:=eval(diff(f,v{\dollar}1),v=v0):
 2607   df[2]:=eval(diff(f,v{\dollar}2),v=v0):
 2608   df[3]:=eval(diff(f,v{\dollar}3),v=v0):
 2609   df[4]:=eval(diff(f,v{\dollar}4),v=v0):
 2610   tmp[1]:=sqrt(df[0])*WeierstrassPPrime(z,g[2],g[3]):
 2611   tmp[2]:=(1/2)*df[1]*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]):
 2612   tmp[3]:=(1/24)*df[0]*df[3]:
 2613   tmp[4]:=2*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]){\tothepower}2:
 2614   tmp[5]:=(1/48)*df[0]*df[4]:
 2615   v:=v0+(tmp[1]+tmp[2]+tmp[3])/(tmp[4]-tmp[5]):
 2616   p:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
 2617   +4*a[3]*v+a[4]:
 2618   testfunc:=(diff(v,z)){\tothepower}2-p:
 2619   testfunc:=simplify(testfunc);\par}
 2620   \leftskip=0mm
 2621   \medskip
 2622   \citindent
 2623   As this result was the only missing link in the formulation of an explicit
 2624   solution to the wave propagation problem in nonlinear magneto-optical media,
 2625   taking into account also weakly phase-mismatched nonlinear source terms, the
 2626   only task remaining now is to formulate the algorithm for solving the inverse
 2627   problem using this more stringent method.
 2628   
 2629   \citem[2006-03-20]{[v.1.41]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2630   Added a few paragraphs on the rigorous theory of wave propagation, clarifying
 2631   the role of the constant of integration $\Gamma$ and its calculation from the
 2632   phase of the transmitted field and the amplitude-related invariants of
 2633   propagation. This now interconnects more naturally to the formulation of the
 2634   wave propagation as an inverse problem, being the natural mode of solving
 2635   for reflectances as well as transmittances.
 2636   I also took the opportunity to write an email to MathWorld, pointing out that
 2637   their solution to the Weierstrass form of the integral equation,
 2638   \.{http://mathworld.wolfram.com/EllipticIntegral.html}, Eqs. (51)--(56),
 2639   actually contains errors; of course I could not resist the opportunity to
 2640   provide the MapleV blocks I used for my own verification, rather than using
 2641   Mathematica code!
 2642   
 2643   \citem[2006-05-01]{[v.1.42]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
 2644   Added support for initialization of the grating structure as a fractal set,
 2645   of the Cantor fractal type. This possibility is in the program now accessed
 2646   via the command-line option \.{--grating fractal cantor [options]}.
 2647   The initialization is done using recursion with the function
 2648   |init_cantor_fractal_grating()|, which was finished today.
 2649   As of today, the \CWEB\ source for the \magbragg\ program (source file
 2650   \.{magbragg.w}) comprises 335649 bytes and 7753 lines of code.
 2651   The size of the compiled (\CYGWIN) executable is 95217 bytes, and the
 2652   PostScript documentation is 1874643 bytes (148 pages of A4 output in 10pt).
 2653   
 2654   \citem[2007-01-10]{[v.1.43]} \.{<http://jonsson.eu>}\hfill\break
 2655   Seefeld, Austria. Midnight. Cleaned up the theoretical part preceeding the
 2656   algorithm of computation and merged all bibliographical references into one
 2657   separate section at the end of the document.
 2658   
 2659   \citem[2011-12-18]{[v.1.44]} \.{<http://jonsson.eu>}\hfill\break
 2660   Updated \.{Makefile}:s for the generation of figures. Also corrected a rather
 2661   stupid way of removing preceeding paths of file names.
 2662   
 2663   @*Compiling the source code. The program is written in \CWEB, generating
 2664   \ANSICEE\ (ISO C90) conforming source code and documentation as plain
 2665   \TeX-source, and is to be compiled using the sequences as outlined in the
 2666   \.{Makefile} listed below.
 2667   \bigskip
 2668   {\obeylines\obeyspaces\tt
 2669   \#
 2670   \# Makefile designed for use with ctangle, cweave, gcc, and plain TeX.
 2671   \#
 2672   \# The CTANGLE program converts a CWEB source document into a C program which
 2673   \# may be compiled in the usual way. The CWEAVE program converts the same CWEB
 2674   \# file into a TeX file that may be formatted and printed in the usual way.
 2675   \#
 2676   \# Copyright (C) 2002-2006, Fredrik Jonsson <fj@@phys.soton.ac.uk>
 2677   \#
 2678   CTANGLE   = ctangle
 2679   CWEAVE    = cweave
 2680   CC        = gcc
 2681   CCOPTS    = -O2 -Wall -ansi -std=iso9899:1990 -pedantic
 2682   LNOPTS    = -lm
 2683   TEX       = tex
 2684   DVIPS     = dvips
 2685   DVIPSOPTS = -ta4 -D1200
 2686   METAPOST  = mp
 2687   ~   ~
 2688   all: magbragg magbragg.ps
 2689   ~   ~
 2690   magbragg: magbragg.o
 2691   ~        \$(CC) \$(CCOPTS) -o magbragg magbragg.o \$(LNOPTS)
 2692   ~   ~
 2693   magbragg.o: magbragg.w
 2694   ~        \$(CTANGLE) magbragg
 2695   ~        \$(CC) \$(CCOPTS) -c magbragg.c
 2696   ~   ~
 2697   magbragg.ps: magbragg.dvi
 2698   ~        \$(DVIPS) \$(DVIPSOPTS) magbragg.dvi -o magbragg.ps
 2699   ~   ~
 2700   magbragg.dvi: magbragg.w
 2701   ~        make -C figures/
 2702   ~        \$(CWEAVE) magbragg
 2703   ~        \$(TEX) magbragg.tex
 2704   ~   ~
 2705   clean:
 2706   ~        make clean -ik -C figures/
 2707   ~        -rm -Rf magbragg *~ *.c *.o *.exe *.dat *.tgz *.pdf
 2708   ~        -rm -Rf *.tex *.aux *.log *.toc *.idx *.scn *.dvi *.ps
 2709   ~   ~
 2710   archive:
 2711   ~        make -ik clean
 2712   ~        tar --gzip --directory=../ -cf magbragg.tgz magbragg
 2713   }
 2714   \bigskip
 2715   This \.{Makefile} essentially executes two major calls. First, the \CTANGLE\
 2716   program parses the \CWEB\ source document \.{magbragg.w} to extract a \CEE\
 2717   source file \.{magbragg.c} which may be compiled in the usual way using any
 2718   \ANSICEE\ conformant compiler. The output source file includes \.{\#line}
 2719   specifications so that any debugging can be done conveniently in terms of
 2720   the original \CWEB\ source file.
 2721   Second, the \CWEAVE\ program parses the same \CWEB\ source file to extract a
 2722   plain \TeX\ source file \.{magbragg.tex} which may be compiled in the usual
 2723   way.
 2724   It takes appropriate care of typographic details like page layout and the use
 2725   of indentation, italics, boldface, and so on, and it supplies extensive
 2726   cross-index information that it gathers automatically.
 2727   
 2728   After having executed \.{make} in the same catalogue where the files
 2729   \.{magbragg.w} and \.{Makefile} are located, one is left with an
 2730   executable file \.{magbragg}, being the ready-to-use compiled program,
 2731   and a PostScript file \.{magbragg.ps}
 2732   which contains the full documentation of the program, that is to say the
 2733   document you currently are reading.
 2734   Notice that on platforms running Windows NT, Windows 2000, Windows ME, or any
 2735   other operating system by Microsoft, the executable file will instead
 2736   automatically be called \.{magbragg.exe}.
 2737   This convention also applies to programs compiled under the \UNIX-like
 2738   environment \CYGWIN.
 2739   
 2740   @*Running the program. The program is entirely controlled by the command
 2741   line options supplied when invoking the program. Since the command line
 2742   for some problems tend to be quite lengthy, since all material parameters
 2743   and optical field inputs to the program must be specified, it is convenient
 2744   to put blocks for the program calls into a Makefile, which makes it easy to
 2745   maintain a structure in the simulations, as well as ensuring traceability
 2746   of the steps in the generation of graphs.
 2747   
 2748   As an example of such a call, the following block is included as an example
 2749   in the enclosed Makefile:
 2750   \bigskip
 2751   {\obeyspaces\obeylines\tt
 2752   ~    testsimulation:
 2753   ~         @@for g in 0.0 1.0 2.0; do {\char'134}
 2754   ~              ./magbragg --verbose --outputfile fig1-\$\$g {\char'134}
 2755   ~                   --spectrumfile fig1-\$\$g.rsp.dat {\char'134}
 2756   ~                   --gratinglength 7.326376e-6 -N 1800 {\char'134}
 2757   ~                   --grating sinusoidal n 2.0550 0.1250 366.3188e-9 {\char'134}
 2758   ~                           g \$\$g'e-3' 0.0 1.0 {\char'134}
 2759   ~                           pe 0.0 0.0 1.0 {\char'134}
 2760   ~                           pm 0.0 0.0 1.0 {\char'134}
 2761   ~                           qe 0.0 0.0 1.0 {\char'134}
 2762   ~                           qm 0.0 0.0 1.0 {\char'134}
 2763   ~                   --refindsurr 2.0550 -M 2000 {\char'134}
 2764   ~                   --lambdastart 1300.0e-9 --lambdastop 1700.0e-9 {\char'134}
 2765   ~                   --trmintensity 7.0e8 7.0e8 1 {\char'134}
 2766   ~                   --trmellipticity 0.0 0.0 1 ;{\char'134}
 2767   ~          done
 2768   }
 2769   
 2770   In the following sections, a complete listing of all command line options
 2771   accepted by the \magbragg\ program is presented.
 2772   
 2773   @*Specifying grating types.
 2774   The \magbragg\ program currently accepts specifications of three different
 2775   main types of gratings:
 2776   stepwise gratings, sinusoidal gratings, and chirped sinusoidal gratings.
 2777   The stepwise gratings are simply stacks of homogeneous layers, stacked to
 2778   form a grating, and these gratings can be composed of two or more different
 2779   materials. As an important subclass of the stepwise gratings, the binary
 2780   gratings are probably the most important ones, being composed of alternating
 2781   layers of only two types of media.
 2782   
 2783   Throughout the program, the following definitions of the material parameters
 2784   apply, to the refractive index $n(z)$, gyration coefficient $g(z)$,
 2785   nonlinear optical parameters $p^{({\rm e})}(z)$ and $q^{({\rm e})}(z)$,
 2786   and nonlinear magneto-optical parameters $p^{({\rm m})}(z)$ and
 2787   $q^{({\rm m})}(z)$,
 2788   $$
 2789     \eqalign{
 2790       |n[k]|&=n_k=[1+\chi^{({\rm ee})}_{xx}]^{1/2},\cr
 2791       |g[k]|&=g_k=i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n_k),\cr
 2792       |pe[k]|&=p^{({\rm e})}_k
 2793         =\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx},\cr
 2794       |qe[k]|&=q^{({\rm e})}_k
 2795         =\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx},\cr
 2796       |pm[k]|&=p^{({\rm m})}_k
 2797         =i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
 2798       |qm[k]|&=q^{({\rm m})}_k
 2799         =i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
 2800     }
 2801   $$
 2802   where |n[k]|, |g[k]|, |pe[k]|, |qe[k]|, |pm[k]|, |qm[k]| denote the variables
 2803   as internally used in the \magbragg\ program to store the corresponding
 2804   material data for the $N-1$ homogeneous segments $z_k\le z<z_{k+1}$,
 2805   $k=1,2,\ldots,N-1$.
 2806   
 2807   In terms of the Verdet constant $V_k$ of a homogeneous layer, as being the
 2808   commonly used measure of the linear magneto-optical rotational strength of
 2809   the material, the $g$-parameter of the \magbragg\ program is expressed as
 2810   $$
 2811     g_k=V_k B^z_0 c/\omega,
 2812   $$
 2813   which simply follows from the general relation
 2814   $$
 2815     i\chi^{({\rm eem})}_{xyz}=2 n c V/\omega.
 2816   $$
 2817   \medskip
 2818   
 2819   @ Stepwise grating structures.
 2820   The stepwise grating structures are specified using the command line option
 2821   \smallskip
 2822   \centerline{\hbox to 40pt{}%
 2823     \.{--grating stepwise} [\.{twolevel}$\langle\ldots\rangle$%
 2824                          $\vert$\.{threelevel}$\langle\ldots\rangle$]\hfill}
 2825   \smallskip\noindent
 2826   where \.{twolevel}, \.{threelevel} etc., states the number of materials
 2827   used in the stacking of the layers.
 2828   For the \.{twolevel} (binary) type of gratings, the syntax is
 2829   \smallskip
 2830   \centerline{\hbox to 40pt{}%
 2831     \.{--grating stepwise twolevel t1} $\langle{t_1}\rangle$
 2832     \.{t2} $\langle{t_2}\rangle$
 2833     \.{n1} $\langle{n_1}\rangle$ \.{n2} $\langle{n_2}\rangle$
 2834     \.{g1} $\langle{g_1}\rangle$ \.{g2} $\langle{g_2}\rangle$
 2835     \hfill}
 2836   \centerline{\hbox to 80pt{}%
 2837     \.{pe1} $\langle{p^{({\rm e})}_1}\rangle$
 2838     \.{pe2} $\langle{p^{({\rm e})}_2}\rangle$
 2839     \.{pm1} $\langle{p^{({\rm m})}_1}\rangle$
 2840     \.{pm2} $\langle{p^{({\rm m})}_2}\rangle$
 2841     \hfill}
 2842   \centerline{\hbox to 80pt{}%
 2843     \.{qe1} $\langle{q^{({\rm e})}_1}\rangle$
 2844     \.{qe2} $\langle{q^{({\rm e})}_2}\rangle$
 2845     \.{qm1} $\langle{q^{({\rm m})}_1}\rangle$
 2846     \.{qm2} $\langle{q^{({\rm m})}_2}\rangle$
 2847     \hfill}
 2848   \smallskip\noindent
 2849   where $t_1$ and $t_2$ are the geometrical layer thicknesses of the
 2850   first two layers $0\le z\le t_1$ and $t_1\le z\le t_1+t_2$, and
 2851   $n_1$ and $n_2$ are the corresponding refractive indices of these
 2852   layers, respectively.
 2853   
 2854   The grating is then composed by repeating the basic pair of layers,
 2855   to give a grating composed of in total $N-1$ homogeneous layers, as
 2856   specified with the \.{-N} option.
 2857   Notice that if the total number of layers $N-1$ is an odd number
 2858   (\ie specifying an even number of interfaces $N$), the last
 2859   layer will possess the same material properties and geometrical
 2860   thickness as the first layer.
 2861   \medskip
 2862   
 2863   @ Sinusoidal structures.
 2864   The sinusoidal grating structures are specified using the command line option
 2865   \smallskip
 2866   \centerline{\hbox to 40pt{}%
 2867     \.{--grating sinusoidal}
 2868     \.{n} $\langle{n_0}\rangle$ $\langle{\Delta n}\rangle$
 2869             $\langle{\Lambda_{n}}\rangle$
 2870     \.{g} $\langle{g_0}\rangle$ $\langle{\Delta g}\rangle$
 2871             $\langle{\Lambda_{g}}\rangle$\hfill}
 2872   \centerline{\hbox to 80pt{}%
 2873     \.{pe} $\langle{p^{({\rm e})}_0}\rangle$
 2874              $\langle{\Delta p^{({\rm e})}_0}\rangle$
 2875              $\langle{\Lambda^{({\rm e})}_{\rm p}}\rangle$
 2876     \.{pm} $\langle{p^{({\rm m})}_0}\rangle$
 2877              $\langle{\Delta p^{({\rm m})}_0}\rangle$
 2878              $\langle{\Lambda^{({\rm m})}_{\rm p}}\rangle$\hfill}
 2879   \centerline{\hbox to 80pt{}%
 2880     \.{qe} $\langle{q^{({\rm e})}_0}\rangle$
 2881              $\langle{\Delta q^{({\rm e})}_0}\rangle$
 2882              $\langle{\Lambda^{({\rm e})}_{\rm q}}\rangle$
 2883     \.{qm} $\langle{q^{({\rm m})}_0}\rangle$
 2884              $\langle{\Delta q^{({\rm m})}_0}\rangle$
 2885              $\langle{\Lambda^{({\rm m})}_{\rm q}}\rangle$\hfill}
 2886   \smallskip\noindent
 2887   In terms of the supplied command line options, the resulting grating structure
 2888   is then described by the continuous distribution of refractive index,
 2889   gyration coefficient, and nonlinear optical and magneto-optical coefficients as
 2890   $$
 2891     \eqalign{
 2892       n(z)&=n_0+\Delta n\sin(2\pi z/\Lambda_{n}),\cr
 2893       g(z)&=g_0+\Delta g\sin(2\pi z/\Lambda_{g}),\cr
 2894       p^{({\rm e})}(z)&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
 2895          \sin(2\pi z/\Lambda^{({\rm e})}_{\rm p}),\cr
 2896       q^{({\rm e})}(z)&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
 2897          \sin(2\pi z/\Lambda^{({\rm e})}_{\rm q}),\cr
 2898       p^{({\rm m})}(z)&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
 2899          \sin(2\pi z/\Lambda^{({\rm m})}_{\rm p}),\cr
 2900       q^{({\rm m})}(z)&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
 2901          \sin(2\pi z/\Lambda^{({\rm m})}_{\rm q}),\cr
 2902     }
 2903   $$
 2904   which in the discretized and oversampled model as used in the internal
 2905   representration of the \magbragg\ program hence becomes
 2906   $$
 2907     \eqalign{
 2908       n_j&=n_0+\Delta n\sin(2\pi z_j/\Lambda_{n}),\cr
 2909       g_j&=g_0+\Delta g\sin(2\pi z_j/\Lambda_{g}),\cr
 2910       p^{({\rm e})}_j&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
 2911          \sin(2\pi z_j/\Lambda^{({\rm e})}_{\rm p}),\cr
 2912       q^{({\rm e})}_j&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
 2913          \sin(2\pi z_j/\Lambda^{({\rm e})}_{\rm q}),\cr
 2914       p^{({\rm m})}_j&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
 2915          \sin(2\pi z_j/\Lambda^{({\rm m})}_{\rm p}),\cr
 2916       q^{({\rm m})}_j&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
 2917          \sin(2\pi z_j/\Lambda^{({\rm m})}_{\rm q}),\cr
 2918     }
 2919   $$
 2920   for $j=1,2,\ldots,N-1$.
 2921   For sinusoidal gratings, discrete phase jumps of the refractive index
 2922   distribution can also be applied, by using the \.{--phasejump} command
 2923   line option. Subsequent apodization of the structure can also be applied,
 2924   using the {--apodize} option.
 2925   \medskip
 2926   
 2927   @ Sinusoidal chirped structures.
 2928   The chirped grating structures, being sinusoidal gratings with a spatially
 2929   varying grating period, are specified using the somewhat extensive command
 2930   line option
 2931   \smallskip
 2932   \centerline{\hbox to 40pt{}%
 2933     \.{--grating chirped}
 2934     \.{n} $\langle{n_0}\rangle$ $\langle{\Delta n}\rangle$
 2935             $\langle{\Lambda_{n}}\rangle$ $\langle{\eta_{n}}\rangle$
 2936     \.{g} $\langle{g_0}\rangle$ $\langle{\Delta g}\rangle$
 2937             $\langle{\Lambda_{g}}\rangle$ $\langle{\eta_{g}}\rangle$\hfill}
 2938   \centerline{\hbox to 80pt{}%
 2939     \.{pe} $\langle{p^{({\rm e})}_0}\rangle$
 2940              $\langle{\Delta p^{({\rm e})}_0}\rangle$
 2941              $\langle{\Lambda^{({\rm e})}_{\rm p}}\rangle$
 2942              $\langle{\eta^{({\rm e})}_{\rm p}}\rangle$
 2943     \.{pm} $\langle{p^{({\rm m})}_0}\rangle$
 2944              $\langle{\Delta p^{({\rm m})}_0}\rangle$
 2945              $\langle{\Lambda^{({\rm m})}_{\rm p}}\rangle$
 2946              $\langle{\eta^{({\rm m})}_{\rm p}}\rangle$\hfill}
 2947   \centerline{\hbox to 80pt{}%
 2948     \.{qe} $\langle{q^{({\rm e})}_0}\rangle$
 2949              $\langle{\Delta q^{({\rm e})}_0}\rangle$
 2950              $\langle{\Lambda^{({\rm e})}_{\rm q}}\rangle$
 2951              $\langle{\eta^{({\rm e})}_{\rm q}}\rangle$
 2952     \.{qm} $\langle{q^{({\rm m})}_0}\rangle$
 2953              $\langle{\Delta q^{({\rm m})}_0}\rangle$
 2954              $\langle{\Lambda^{({\rm m})}_{\rm q}}\rangle$
 2955              $\langle{\eta^{({\rm m})}_{\rm q}}\rangle$\hfill}
 2956   \smallskip\noindent
 2957   Here $\langle{n_0}\rangle$ is the bias refractive index across the grating,
 2958   $\langle{\Delta n}\rangle$ the modulation of the refractive index around the
 2959   bias value, that is to say half the bottom-to-peak value of the modulated
 2960   index of refraction, $\langle{\Lambda_{n}}\rangle$ is the initial geometrical
 2961   grating period at $z=0$,
 2962   and $\langle{\eta_{n}}\rangle$ the chirp of the grating, being the
 2963   relative change of the grating period over the length of the grating.
 2964   The other grating parameters are specified analogously, for gyration
 2965   coefficient and nonlinear optical and magneto-optical coefficients.
 2966   The chirp parameter is here defined as the change in geometrical grating period
 2967   per unit geometrical distance along the grating, or
 2968   $$
 2969     \eta_{n}={{\Lambda(L)-\Lambda(0)}\over{L}}
 2970   $$
 2971   where $\Lambda(z)$ denotes the geometrical grating period as function of
 2972   the spatial coordinate $z$ along the grating.
 2973   
 2974   To illustrate the meaning of the chirp parameter, consider a chirped refractive
 2975   index distribution over a geometrical distance $L$ and with a bias refractive
 2976   index $n_0$. To give a resonance in reflection ranging from vacuum wavelength
 2977   $\lambda_{\rm a}$ to $\lambda_{\rm b}$, say, the grating period could be either
 2978   increasing or decreasing with spatial coordinate $z$. By choosing the initial
 2979   part of the grating (at $z=0$) to be resonant in reflection for a vacuum
 2980   wavelength $\lambda_{\rm a}$, the initial grating period $\Lambda_{n}$ should
 2981   be chosen as half the optical period at resonance, or
 2982   $$
 2983     \Lambda_{n}={{\lambda_{\rm a}}\over{2 n_0}}.
 2984   $$
 2985   With this initial grating period the chirp parameter should, in order to give
 2986   a final resonance in reflection at vacuum wavelength $\lambda_{\rm b}$ at the
 2987   end of the grating (at $z=L$), then simply be chosen as
 2988   $$
 2989     \eta_{n}={{\lambda_{\rm b}-\lambda_{\rm a}}\over{2 n_0 L}}.
 2990   $$
 2991   Notice that whenever $\lambda_{\rm b}<\lambda_{\rm a}$, the chirp parameter
 2992   is negative, indicating a grating period which is decreasing with increasing
 2993   spatial coordinate $z$. This convention of sign for the chirp parameter is
 2994   consistently kept throughout the algorithms of the \magbragg\ program.
 2995   
 2996   In terms of the supplied command line options, the resulting chirped grating
 2997   structure is described by the continuous distribution of refractive index,
 2998   gyration coefficient, and nonlinear optical and magneto-optical coefficients as
 2999   $$
 3000     \eqalign{
 3001       n(z)&=n_0+\Delta n\sin((2\pi/\eta_{n})\ln(1+\eta_{n}z/\Lambda_{n})),\cr
 3002       g(z)&=g_0+\Delta g\sin((2\pi/\eta_{g})\ln(1+\eta_{g}z/\Lambda_{g})),\cr
 3003       p^{({\rm e})}(z)&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
 3004          \sin((2\pi/\eta^{({\rm e})}_{\rm p})
 3005          \ln(1+\eta^{({\rm e})}_{\rm p}z/\Lambda^{({\rm e})}_{\rm p})),\cr
 3006       p^{({\rm m})}(z)&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
 3007          \sin((2\pi/\eta^{({\rm m})}_{\rm p})
 3008          \ln(1+\eta^{({\rm m})}_{\rm p}z/\Lambda^{({\rm m})}_{\rm p})),\cr
 3009       q^{({\rm e})}(z)&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
 3010          \sin((2\pi/\eta^{({\rm e})}_{\rm q})
 3011          \ln(1+\eta^{({\rm e})}_{\rm q}z/\Lambda^{({\rm e})}_{\rm q})),\cr
 3012       q^{({\rm m})}(z)&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
 3013          \sin((2\pi/\eta^{({\rm m})}_{\rm q})
 3014          \ln(1+\eta^{({\rm m})}_{\rm q}z/\Lambda^{({\rm m})}_{\rm q})),\cr
 3015     }
 3016   $$
 3017   which in the discretized and oversampled model as used in the internal
 3018   representration of the \magbragg\ program hence becomes
 3019   $$
 3020     \eqalign{
 3021       n_j&=n_0+\Delta n\sin((2\pi/\eta_{n})\ln(1+\eta_{n}z_j/\Lambda_{n})),\cr
 3022       g_j&=g_0+\Delta g\sin((2\pi/\eta_{g})\ln(1+\eta_{g}z_j/\Lambda_{g})),\cr
 3023       p^{({\rm e})}_j&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
 3024          \sin((2\pi/\eta^{({\rm e})}_{\rm p})
 3025          \ln(1+\eta^{({\rm e})}_{\rm p}z_j/\Lambda^{({\rm e})}_{\rm p})),\cr
 3026       p^{({\rm m})}_j&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
 3027          \sin((2\pi/\eta^{({\rm m})}_{\rm p})
 3028          \ln(1+\eta^{({\rm m})}_{\rm p}z_j/\Lambda^{({\rm m})}_{\rm p})),\cr
 3029       q^{({\rm e})}_j&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
 3030          \sin((2\pi/\eta^{({\rm e})}_{\rm q})
 3031          \ln(1+\eta^{({\rm e})}_{\rm q}z_j/\Lambda^{({\rm e})}_{\rm q})),\cr
 3032       q^{({\rm m})}_j&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
 3033          \sin((2\pi/\eta^{({\rm m})}_{\rm q})
 3034          \ln(1+\eta^{({\rm m})}_{\rm q}z_j/\Lambda^{({\rm m})}_{\rm q})),\cr
 3035     }
 3036   $$
 3037   for $j=1,2,\ldots,N-1$.
 3038   
 3039   Notice that the geometrical period of any of the optical/physical properties
 3040   described by the above distributions is given by
 3041   $$
 3042     {{2\pi}\over{\{{\rm geometrical\ period}\}}}=
 3043       {{\partial}\over{\partial z}}\{{\rm argument\ of\ }\sin(\ldots)\}.
 3044   $$
 3045   For example, the refractive index distribution
 3046   $$
 3047     n(z)=n_0+\Delta n\sin((2\pi/\eta_{n})\ln(1+\eta_{n}z/\Lambda_{n}))
 3048   $$
 3049   has its spatially varying local grating period $\Lambda_{\rm loc}(z)$ given by
 3050   $$
 3051     \eqalign{
 3052       {{2\pi}\over{\Lambda_{\rm loc}(z)}}
 3053         &={{\partial}\over{\partial z}}
 3054           [({{2\pi}/{\eta_{n}}})\ln(1+{{\eta_{n}z}/{\Lambda_{n}}})]%\cr
 3055         =({{2\pi}/{\eta_{n}}})
 3056           {{{{\eta_{n}}/{\Lambda_{n}}}}\over{(1+{{\eta_{n}z}/{\Lambda_{n}}})}}%\cr
 3057         ={{2\pi}\over{(\Lambda_{n}+\eta_{n}z)}}%\cr
 3058   }
 3059   $$
 3060   that is to say, the geometrical local period is given as a linear function
 3061   which in terms of the vacuum resonance wavelengths $\lambda_{\rm a}$ and
 3062   $\lambda_{\rm b}$ becomes
 3063   $$
 3064     \eqalign{
 3065       \Lambda_{\rm loc}(z)&=\Lambda_n+\eta z
 3066         ={{\lambda_{\rm a}}\over{2n_0}}
 3067           +{{(\lambda_{\rm b}-\lambda_{\rm a})}\over{2n_0L}}z
 3068         ={{1}\over{2n_0}}(\lambda_{\rm a}+(\lambda_{\rm b}-\lambda_{\rm a})z/L).
 3069   }
 3070   $$
 3071   For the sake of consistency with the discussion earlier in this section,
 3072   $\lambda_{\rm a}$ is taken as the vacuum resonance wavelength at $z=0$,
 3073   while $\lambda_{\rm b}$ is the corresponding wavelength of resonance at $z=L$.
 3074   For chirped gratings, as well as for the sinusoidal gratings, discrete phase
 3075   jumps of the refractive index distribution can also be applied, by using the
 3076   \.{--phasejump} command line option. Subsequent apodization of the structure
 3077   can also be applied, using the {--apodize} option.
 3078   \medskip
 3079   
 3080   @ Fractal structures.
 3081   
 3082   [TEXT STILL TO BE WRITTEN]
 3083   
 3084   @ Discrete phase jumps.
 3085   Discrete phase jumps in sinusoidal type gratings (of sinusoidal of chirped
 3086   type as previously described)
 3087   can be specified using the \.{--phasejump} option, with syntax
 3088   \smallskip
 3089   \centerline{\hbox to 40pt{}%
 3090     \.{--phasejump} $\langle{\varphi_{\rm jump}}\rangle$
 3091     $\langle{z_{\rm jump}}\rangle$\hfill}
 3092   \smallskip\noindent
 3093   where $\varphi_{\rm jump}$ is the phase shift in radians to be applied for
 3094   the grating at all spatial coordinates $z\ge z_{\rm jump}$.
 3095   For sinusoidal type gratings, the effect is that the refractive index and
 3096   gyration coefficient distributions become
 3097   $$
 3098     \eqalign{
 3099       n(z)&=n_0+\Delta n\sin(2\pi z/\Lambda_{n}+\varphi(z)),\cr
 3100       g(z)&=g_0+\Delta g\sin(2\pi z/\Lambda_{g}+\varphi(z)),\cr
 3101     }
 3102   $$
 3103   where
 3104   $$
 3105     \varphi(z)=\cases{0,&$z<z_{\rm jump}$\cr
 3106                       \varphi_{\rm jump},&$z\ge z_{\rm jump}$\cr},
 3107   $$
 3108   Notice that the parameters supplied with the \.{--phasejump} option
 3109   only affects the (linear) refractive index and gyration coefficient
 3110   distributions $n(z)$ and $g(z)$; all other (nonlinear) material parameters
 3111   are left unaffected, irregardless of potential spatial modulation schemes.
 3112   
 3113   @ The refractive index surrounding the grating.
 3114   The refractive index surrounding the grating is specified using the command
 3115   line option
 3116   \smallskip
 3117   \centerline{\hbox to 40pt{}\.{--refindsurr}
 3118     $\langle n_{\rm ext}\rangle$\hfill}
 3119   \smallskip\noindent
 3120   where $\langle n_{\rm ext}\rangle$ is the refractive index surrounding the
 3121   grating.
 3122   If the surrounding refractive index is not specified at the command line
 3123   at execution of the program, a default value of $n_{\rm ext}=1.0$ (vacuum)
 3124   is used in the simulation.
 3125   
 3126   @ Apodization of the grating.
 3127   Apodization of the grating structure is typically applied
 3128   in order to get rid of any occurring Gibbs oscillations due to a rapid
 3129   change of the index modulation at the ends of the grating.
 3130   For a more detailed description of Gibbs oscillations, see for example
 3131   Refs.~[14,15].
 3132   By applying apodization, the \magbragg\ program force a smoother
 3133   transition between modulated and non-modulated regions of the grating.
 3134   The apodization is invoked by the \.{--apodize}
 3135   option, with syntax
 3136   \smallskip
 3137   \centerline{\hbox to 40pt{}%
 3138     \.{--apodize} $\langle{L_{\rm apod}}\rangle$\hfill}
 3139   \smallskip\noindent
 3140   where $L_{\rm apod}$ is the apodization length at each end of the grating.
 3141   The apodization is performed at the ends of the grating according to a
 3142   multiplicative factor of the modulation amplitudes of the
 3143   refractive index and gyration coefficient, of the form
 3144   $$
 3145     f(z)=\cases{
 3146       [1-\cos(\pi z/L_{\rm apod})]/2,&$0\le z\le L_{\rm apod}$,\cr
 3147       1,&$L_{\rm apod}<z<L-L_{\rm apod}$,\cr
 3148       [1-\cos(\pi(z-L)/L_{\rm apod})]/2,&$L-L_{\rm apod}\le z\le L$,\cr
 3149     }
 3150   $$
 3151   and otherwise $f(z)=0$, for any $z$ outside the above domains of definition,
 3152   where $L_{\rm apod}$ is the effective apodization length, being the floating
 3153   point parameter specified after the \.{--apodize} option, and $L$ the
 3154   geometrical overall length of the grating, \eg as specified with the
 3155   \.{--gratinglength} option.
 3156   Notice that as in the previously described \.{--phasejump} option,
 3157   the parameter supplied with the \.{--apodize} option
 3158   only apodizes the (linear) refractive index and gyration coefficient
 3159   distributions $n(z)$ and $g(z)$; all other (nonlinear) material parameter
 3160   distributions are left unaffected.
 3161   
 3162   @ Specifying transmitted intensity.
 3163   The generated data relating a specified optical output to an optical input can
 3164   in the program automatically be iterated over a range of values of the
 3165   transmitted optical intensity, expressed in regular \SI\ units as Watts per
 3166   square meter (${\rm W}/{\rm m}^2$).
 3167   The command line syntax for specifying that the
 3168   program should generate the inverse relation for $M_{\rm i}$ discrete values of
 3169   the transmitted optical intensity in a range from $I_{\rm start}$ to
 3170   $I_{\rm stop}$ is
 3171   \smallskip
 3172   \centerline{\hbox to 40pt{}\.{--trmintensity}
 3173     $\langle I_{\rm start}\rangle$ $\langle I_{\rm stop}\rangle$
 3174     $\langle M_{\rm i}\rangle$\hfill}
 3175   \smallskip\noindent
 3176   Notice that parameters throughout the program are to be specified in terms
 3177   of regular \SI\ units. In case the in optical physics quite commonly used
 3178   quantity of gigawatts per square centimeter is preferred, just use the
 3179   conversion $1\,{\rm G}{\rm W}/{\rm cm}^2=10^{13}\,{\rm W}/{\rm m}^2$.
 3180   \smallskip\noindent
 3181   
 3182   @ Specifying transmitted ellipticity.
 3183   The command line syntax for specification of the range of ellipticity of the
 3184   transmitted polarization state is analogous to that of the transmitted
 3185   intensity, as
 3186   \smallskip
 3187   \centerline{\hbox to 40pt{}\.{--trmellipticity}
 3188     $\langle \epsilon_{\rm start}\rangle$ $\langle \epsilon_{\rm stop}\rangle$
 3189     $\langle M_{\rm e}\rangle$\hfill}
 3190   \smallskip\noindent
 3191   where $\langle \epsilon_{\rm start}\rangle$ and
 3192   $\langle \epsilon_{\rm stop}\rangle$ are the start and stop values for the
 3193   normalized transmitted ellipticity~$\epsilon$, which in terms of the
 3194   transmitted Stokes parameters is defined as $\epsilon\equiv W_3/W_0$.
 3195   (For the definitions of the Stokes parameters in terms of the electric
 3196   field of the light wave, see the corresponding separate section included
 3197   in this documentation.)
 3198   Here $\epsilon=-1$ corresponds to right circular polarization (RCP) while
 3199   $\epsilon=1$ corresponds to left circular polarization (LCP), with
 3200   $\epsilon=0$ corresponding to linear polarization.
 3201   Values intermediate of those give the various degrees of elliptic polarization
 3202   states. As in the case of specification of the transmitted intensity,
 3203   $\langle M_{\rm e}\rangle$ is the number of discrete steps of the ellipticity
 3204   that will be iterated over in the simulation.
 3205   
 3206   @ Specifying optical vacuum wavelength interval to be scanned.
 3207   For the sampling of optical spectra, with the reflectance and transmittance
 3208   sampled as function of optical vacuum wavelength, the interval of computation
 3209   is specified using the syntax
 3210   \smallskip
 3211   \centerline{\hbox to 40pt{}
 3212     \.{--lambdastart} $\langle \lambda_{\rm start}\rangle$
 3213     \.{--lambdastop} $\langle \lambda_{\rm stop}\rangle$\hfill}
 3214   \smallskip\noindent
 3215   where $\lambda_{\rm start}$ and $\lambda_{\rm stop}$ specifies the wavelength
 3216   domain. The number of samples $M$ to be calculated is specified using the
 3217   syntax
 3218   \smallskip
 3219   \centerline{\hbox to 40pt{}
 3220     \.{-M} $\langle M\rangle$\hfill}
 3221   \smallskip\noindent
 3222   The specific discrete vacuum wavelength $\lambda_k$ at which the computation
 3223   is performed are
 3224   $$
 3225     \lambda_k=\lambda_{\rm start}+{{(k-1)}\over{(M-1)}}
 3226       (\lambda_{\rm stop}-\lambda_{\rm start}),
 3227   $$
 3228   for $k=1,2,\ldots,M$.
 3229   
 3230   @ Scaling of Stokes parameters to yield optical intensity.
 3231   To force the output Stokes parameters to be expressed in terms of optical
 3232   intensity units of Watts per square meter, rather than the regular square
 3233   Volts per meter, use the command line option
 3234   \smallskip
 3235   \centerline{\hbox to 40pt{}\.{--scale\_stokesparams 1.327209e-3}\hfil}
 3236   \smallskip\noindent
 3237   forcing the program to save the scaled Stokes parameters
 3238   $S'_k=1.327209\times10^{-3}S_k$ to file instead of the original $S_k$,
 3239   $k=0,1,2,3$.
 3240   As a default, and as a matter of convention of electrodynamics in \SI\ units,
 3241   all Stokes parameters are given in ${\rm V}^2/{\rm m}^2$, through their
 3242   definition.
 3243   For example, the incident field (which is calculated by the program in
 3244   this inverse formulation of the problem) is expressed in terms of the Stokes
 3245   parameters as
 3246   $$
 3247   \eqalign{
 3248     S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
 3249     S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
 3250     S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
 3251     S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
 3252   }
 3253   $$
 3254   However, the direct interpretation of these quantities in terms of squared
 3255   Volts per square metres is sometimes somewhat inconvenient; therefore, those
 3256   parameters can be scaled to give an interpretation of the intensity (in regular
 3257   \SI\ units measured in Watts per square metres),
 3258   as $S'_k=(\varepsilon_0 c/2)S_k$, or explicitly
 3259   $$
 3260   \eqalign{
 3261     S'_0&=(\varepsilon_0 c/2)
 3262        [\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2],\qquad
 3263     S'_1=(\varepsilon_0 c/2)
 3264        2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
 3265     S'_3&=(\varepsilon_0 c/2)
 3266        [\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2],\qquad
 3267     S'_2=(\varepsilon_0 c/2)
 3268        2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
 3269   }
 3270   $$
 3271   In this representation, $S'_0$ is now identical to the incident intensity
 3272   $I_{\rm in}$ [${\rm W}/{\rm m}^2$].
 3273   In order to have those scaled Stokes parameters $S'_k$ written to file,
 3274   rather than the default ones, one convenient possibility is to use the
 3275   previously added \.{--scale\_stokesparams} option, to include
 3276   \.{--scale\_stokesparams 1.327209e-3} at the command line when invoking
 3277   the program.
 3278   The numerical value of this scaling was obtained
 3279   from
 3280   $$
 3281     \eqalign{
 3282       \varepsilon_0 c/2
 3283         &=(8.854187817\ldots\times 10^{-12}\ {\rm F}/{\rm m})
 3284           \times(2.99792458\times 10^8\ {\rm m}/{\rm s})/2\cr
 3285         &\approx 1.327209\times 10^{-3}\ {\rm F}/{\rm s}.\cr
 3286     }
 3287   $$
 3288   In regular \SI\ units as here used, the physical dimension of the
 3289   quantity $\varepsilon_0 c/2$ is $[({\rm A}\cdot{\rm s})/({\rm V}\cdot{\rm m})]
 3290   \cdot[{\rm m}/{\rm s}]=[{\rm A}/{\rm V}]$, so the physical dimension of
 3291   $(\varepsilon_0 c/2)S_k$ is hence $[{\rm A}/{\rm V}]\cdot[{\rm V}^2/{\rm m}^2]
 3292   =[{\rm W}/{\rm m}^2]$, as expected for an intensity measure (energy flow per
 3293   unit area in the plane orthogonal to the direction of wave propagation).
 3294   For any other scaling factor of the Stokes parameters, use the general syntax
 3295   \smallskip
 3296   \centerline{\hbox to 40pt{}\.{--scale\_stokesparams}
 3297     $\langle a\rangle$\hfill}
 3298   \smallskip\noindent
 3299   which forces the program to save the scaled Stokes parameters
 3300   $S'_k=a S_k$ to file instead of the original $S_k$, $k=0,1,2,3$.
 3301   
 3302   @ Saving intra-grating spatial evolution of optical field and intensity.
 3303   The optical intensity and/or general spatial evolution of the electromagnetic
 3304   field inside the grating can be saved to file using the command line option
 3305   of syntax
 3306   \smallskip
 3307   \centerline{\hbox to 40pt{}
 3308     \.{-M} $\langle M\rangle$\hfill}
 3309   \smallskip\noindent
 3310   
 3311   The data for the field evolution is written to file in the format
 3312   \smallskip
 3313   \centerline{\hbox to 20pt{}
 3314     $z_1$\quad
 3315     $\langle E^{\rm f}_+(z_1)\rangle$\quad
 3316     $\langle E^{\rm f}_-(z_1)\rangle$\quad
 3317     $\langle E^{\rm b}_+(z_1)\rangle$\quad
 3318     $\langle E^{\rm b}_-(z_1)\rangle$\quad
 3319   \hfill}
 3320   \centerline{\hbox to 20pt{}
 3321     $z_2$\quad
 3322     $\langle E^{\rm f}_+(z_2)\rangle$\quad
 3323     $\langle E^{\rm f}_-(z_2)\rangle$\quad
 3324     $\langle E^{\rm b}_+(z_2)\rangle$\quad
 3325     $\langle E^{\rm b}_-(z_2)\rangle$\quad
 3326   \hfill}
 3327   \centerline{\hbox to 20pt{}
 3328     $\vdots$\hskip 80pt$\vdots$\hskip 80pt$\vdots$
 3329   \hfill}
 3330   \centerline{\hbox to 20pt{}
 3331     $z_N$\quad
 3332     $\langle E^{\rm f}_+(z_N)\rangle$\quad
 3333     $\langle E^{\rm f}_-(z_N)\rangle$\quad
 3334     $\langle E^{\rm b}_+(z_N)\rangle$\quad
 3335     $\langle E^{\rm b}_-(z_N)\rangle$\quad
 3336   \hfill}
 3337   \smallskip\noindent
 3338   where each blank space-separated entry $\langle E^{\rm f}_+(z_k)\rangle$,
 3339   $\langle E^{\rm f}_-(z_k)\rangle$, $\langle E^{\rm b}_+(z_k)\rangle$, or
 3340   $\langle E^{\rm b}_-(z_k)\rangle$ for an electric field component constitutes
 3341   the pair of its real and imaginary parts,
 3342   $$
 3343     \langle E^{\rm f}_+(z_k)\rangle\equiv
 3344       \langle{\re}[E^{\rm f}_+(z_k)]\rangle\quad
 3345       \langle{\im}[E^{\rm f}_+(z_k)]\rangle,
 3346   $$
 3347   where each number $\langle{\re}[E^{\rm f}_+(z_k)]\rangle$ or
 3348   $\langle{\im}[E^{\rm f}_+(z_k)]\rangle$ in the pair in the saved file
 3349   is represented in plain ASCII by 16 significant digits.
 3350   
 3351   [TEXT STILL TO BE WRITTEN]
 3352   
 3353   @ Saving the spatial profile of grating structure.
 3354   The spatial distribution of the refractive index, gyration coefficient, and
 3355   nonlinear optical and magneto-optical parameters can in the progress of the
 3356   simulation be written to file using the command line option
 3357   \smallskip
 3358   \centerline{\hbox to 40pt{}\.{--writegratingfile}
 3359     $\langle {\rm filename}\rangle$\hfill}
 3360   \smallskip\noindent
 3361   [TEXT STILL TO BE WRITTEN]
 3362   
 3363   @ Intragrating intensity information.
 3364   In many cases the density distribution of optical intensity inside the medium
 3365   is of particular interest, since cavity-effects or other resonant phenomena
 3366   can considerably increase the intensity locally along the grating.
 3367   The program can automatically track down the maximum present intensity in the
 3368   grating and the corresponding location, presenting the information either at
 3369   the terminal window in which the program was started or written to file.
 3370   The syntax for getting this information calculated and displayed in the
 3371   terminal window is simply
 3372   \smallskip
 3373   \centerline{\hbox to 40pt{}\.{--intensityinfo}.\hfill}
 3374   \smallskip\noindent
 3375   To get the information instead written to file, use
 3376   \smallskip
 3377   \centerline{\hbox to 40pt{}\.{--intensityinfologfile}
 3378   $\langle{\rm filename}\rangle$,\hfill}
 3379   \smallskip\noindent
 3380   where $\langle{\rm filename}\rangle$ is the name of the destination file.
 3381   
 3382   @*Postprocessing of the data to get the direct relation.
 3383   The data generated by the program naturally relate the inverse relation between
 3384   the incident and transmitted (or reflected) optical fields.
 3385   In other words, the input data are typically equidistantly spaced in the
 3386   transmitted intensity and/or ellipticity, while the spacing of the
 3387   calculated data (the incident optical field) is ....
 3388   
 3389   For topological mappings of the data, such as in Fig.~X [FIGURE TO BE
 3390   INSERTED], it is for most cases of no importance whether it is the
 3391   direct relation (transmitted or reflected field as function of incident field)
 3392   or its inverse (incident or reflected field as function of transmitted field)
 3393   that is described by the set of data.
 3394   However, in many cases we are interested in a maping that corresponds to
 3395   a direct experimental setup. For example, whenever we have a linearly
 3396   polarized incident light in the experimental setup of evaluation, the
 3397   transmitted polarization state generally differ from the input one, and
 3398   we must take into account that the input data will ....
 3399   
 3400   [TEXT STILL TO BE WRITTEN]
 3401   
 3402   @*The main program. Here follows the general outline of the main program.
 3403   
 3404   @c
 3405   @<Library inclusions@>@;
 3406   @<Global definitions@>@;
 3407   @<Data structure definitions@>@;
 3408   @<Global variables@>@;
 3409   @<Subroutines@>@;
 3410   
 3411   int main(int argc, char *argv[])
 3412   {
 3413      @<Declaration of local variables@>@;
 3414      @<Initialize variables@>@;
 3415      @<Parse command line for parameter values@>@;
 3416      @<Check for specified trajectory of transmitted Stokes parameters@>@;
 3417      @<Open files for output@>@;
 3418      @<Allocate optical field vectors@>@;
 3419      @<Initiate grating structure@>@;
 3420      @<Initiate surrounding medium@>@;
 3421      @<Calculate intragrating layer reflectances@>@;
 3422      @<Calculate incident optical field spectrum@>@;
 3423      @<Print information on maximum optical intensity in grating@>@;
 3424      @<Deallocate optical field vectors@>@;
 3425      @<Close output files@>@;
 3426      return(SUCCESS);
 3427   }
 3428   
 3429   @ The standard \ANSICEE\ libraries included in this program are:\par
 3430   \varitem[\.{math.h}]{For access to mathematical functions.}
 3431   \varitem[\.{time.h}]{For time stamps and estimation of computation time.}
 3432   \varitem[\.{stdio.h}]{For file access and any block involving |fprintf|.}
 3433   \varitem[\.{stdlib.h}]{For memory allocation, |malloc|, |exit|, |free| etc.}
 3434   \varitem[\.{string.h}]{For string manipulation, |strcpy|, |strcmp| etc.}
 3435   \varitem[\.{ctype.h}]{For access to the |isalnum| routine.}
 3436   
 3437   @<Library inclusions@>=
 3438   #include <math.h>
 3439   #include <time.h>
 3440   #include <stdio.h>
 3441   #include <stdlib.h>
 3442   #include <string.h>
 3443   #include <ctype.h>
 3444   
 3445   @ Global definitions.
 3446   There are just a few global definitions present in the \magbragg\ program:\par
 3447   \varitem[\.{VERSION}]{The current program revision number.}
 3448   \varitem[\.{COPYRIGHT}]{The copyright banner.}
 3449   \varitem[\.{SUCCESS}]{The return code for successful program termination.}
 3450   \varitem[\.{FAILURE}]{The return code for unsuccessful program termination.}
 3451   \varitem[\.{NCHMAX}]{The maximum number of characters allowed in strings for
 3452     storing file names, including path.}
 3453   
 3454   @<Global definitions@>=
 3455   #define VERSION "1.43"
 3456   #define COPYRIGHT "Copyright (C) 2002-2007, Fredrik Jonsson"
 3457   #define SUCCESS (0)
 3458   #define FAILURE (1)
 3459   #define NCHMAX (256)
 3460   
 3461   @ Data structure definitions.
 3462   The |dcomplex| data structure contains real and imaginary parts in
 3463   double precision, and is also the basic data structure used for the
 3464   allocation of complex valued vectors of double precision.
 3465   
 3466   @<Data struct...@>=
 3467   typedef struct DCOMPLEX {double r,i;} dcomplex;
 3468   
 3469   @ Declaration of global variables. The only global variables allowed in
 3470   my programs are |optarg|, which is a pointer to the the string of characters
 3471   that specified the call from the command line, and |progname|, which simply
 3472   is a pointer to the string containing the name of the program, as it was
 3473   invoked from the command line.
 3474   
 3475   @<Global variables@>=
 3476   extern char *optarg;
 3477   char *progname;
 3478   
 3479   @ Listing of subroutines called by the main program.
 3480   
 3481   @<Subroutines@>=
 3482      @<Routine for checking for numerical characters@>@;
 3483      @<Routine for initialization of Cantor type fractal gratings@>@;
 3484      @<Routines for removing preceding path of filenames@>@;
 3485      @<Routines for memory allocation of vectors@>@;
 3486      @<Routines for generation of random numbers@>@;
 3487      @<Routines for complex arithmetics@>@;
 3488      @<Routines for displaying help message@>@;
 3489   
 3490   @*Declaration of local variables of the main program.
 3491   In \CWEB\ one has the option of adding variables along the program, for example
 3492   by locally adding temporary variables related to a given sub-block of code.
 3493   However, my philosophy in the \magbragg\ program is to keep all variables of
 3494   the |main| section collected together, so as to simplify tasks as, for example,
 3495   tracking down a given variable type definition.
 3496   
 3497   [ADD A LIST OF VARIABLE DESCRIPTIONS WITH THE 'VARITEM' MACRO]
 3498   
 3499   \varitem[|somevariable|]{Some description of |somevariable|.}
 3500   
 3501   @<Declaration of local variables@>=
 3502     @<Physical and mathematical constants@>@;
 3503     @<Time variables@>@;
 3504     @<Declaration of complex arrays storing the electrical field distribution@>@;
 3505     @<Declaration of Boolean variables for execution control@>@;
 3506     @<Discretization parameters@>@;
 3507     @<Grating parameters@>@;
 3508     @<Declaration of file pointers@>@;
 3509     @<Declaration of strings and file names@>@;
 3510     @<Declaration of local dummy variables@>@;
 3511      long nne,jje,mmtraject;
 3512      long ranseed; /* seed for random number generator */
 3513      long maxintens_layer=0;
 3514      int fractal_level=0; /* The recursion level in construction of Cantor-type fractal gratings */
 3515      int maximum_fractal_level=0; /* The maximum allowed recursion level in
 3516                                  construction of Cantor-type fractal gratings */
 3517      double *w0traj=NULL,*w3traj=NULL;
 3518      double lambdastart; /* The start vacuum wavelength $\lambda_{\rm start}$
 3519         of the spectrum to be sampled */
 3520      double lambdastop; /* The stop vacuum wavelength $\lambda_{\rm stop}$
 3521         of the spectrum to be sampled */
 3522      double lambda; /* Dummy variable to hold the vacuum wavelength at a
 3523         discrete spectral sample */
 3524      double omega; /* Ditto for the angular frequency
 3525         $\omega\equiv 2\pi/\lambda$ */
 3526      double ievolambda;
 3527      double apolength; /* Length $L_{\rm apod}$ over which each end of the
 3528         grating should be apodized */
 3529      double phasejumpangle; /* The magnitude of the phase discontinuity
 3530         $\varphi_{\rm jump}$ measured in radians */
 3531      double phasejumpposition; /* The position $z_{\rm jump}$ in metres of the
 3532          phase discontinuity $\varphi_{\rm jump}$ */
 3533      double phi; /* Dummy variable to hold the reference phase over the spatial
 3534          extent of the grating */
 3535      double gyroperturb_position; /* The position $z_{\rm p}$ in metres of the
 3536          peak of the added Lorentzian perturbation $\Delta g(z)$ of the gyration
 3537          coefficient $g(z)$ */
 3538      double gyroperturb_amplitude; /* The zero-to-peak amplitude $a_{\rm p}$ of
 3539          the added Lorentzian perturbation $\Delta g(z)$ of the gyration
 3540          coefficient $g(z)$ */
 3541      double gyroperturb_width; /* The full width at half maximum $w_{\rm p}$ of
 3542          the added Lorentzian perturbation $\Delta g(z)$ of the gyration
 3543          coefficient $g(z)$ */
 3544      double nsurr; /* The linear index of refraction of the medium surrounding
 3545          the grating */
 3546      double n1,n2,t1,t2,nper,ncrp,g1,g2,gper,gcrp,
 3547             pe1,pe2,peper,pecrp,pm1,pm2,pmper,pmcrp,
 3548             qe1,qe2,qeper,qecrp,qm1,qm2,qmper,qmcrp;
 3549      double modn1,modt1,modg1,modpe1,modpm1,modqe1,modqm1,
 3550             aafp2,aafm2,aabp2,aabm2;
 3551      double trmintensity,trmintenstart,trmintenstop,
 3552             trmellipticity,trmellipstart,trmellipstop,stoke_scalefactor;
 3553      static double nndef=600;          /* Number of samples in spectrum    */
 3554      static double mmdef=1000;         /* Number of samples in grating     */
 3555      static double mmedef=1;           /* Number of samples in ellipticity */
 3556      static double mmidef=1;           /* Number of samples in intensity   */
 3557      static double lldef=0.050;        /* Length of grating in metres      */
 3558      static double nsurrdef=1.0;       /* Default surrounding refractive index */
 3559      static double lambdastartdef=1536.0e-9,lambdastopdef=1546.0e-9;
 3560   
 3561   @ Declaration of numerical values of physical constants. All calculations
 3562   performed by this program are done in \SI\ units, in which the fundamental
 3563   physical constants take the values below.
 3564   
 3565   @<Physical and mathematical constants@>=
 3566     static double pi=3.1415926535897932384626433832795; /* $\pi$ */
 3567     static double twopi=2.0*3.1415926535897932384626433832795; /* $2\pi$ */
 3568     static double c=2.997925e8; /* Speed of light in vacuum, $c$ [m/s] */
 3569     static double epsilon0=8.854e-12; /* Permittivity of vacuum, $\varepsilon_0$ [As/Vm] */
 3570   
 3571   @ Declaration of time variables. Here any variables related to timing and
 3572   estimation of computing performance are declared. The significance of the
 3573   variables are as follows:
 3574   \varitem[|initime|]{The time at which the \magbragg\ program is initialized.
 3575     This variable is initialized already in its declaration.}
 3576   \varitem[|now|]{Dummy variable for extraction of current time from the system.}
 3577   \varitem[|eta|]{Estimated time of arrival (ETA, not to be confused with the
 3578     Greek letter $\eta$) of successful termination of the \magbragg\ program.}
 3579   
 3580   @<Time variables@>=
 3581      time_t initime=time(NULL), now=time(NULL), eta=time(NULL);
 3582   
 3583   @ Declaration of pointers to arrays of fields of |dcomplex| class, holding the
 3584   intra-grating electrical field distribution.
 3585   These pointers will after the memory allocation for complex-valued vectors
 3586   hold the spatial distribution of the electric field inside the grating.
 3587   The significance of the variables are as follows:\par
 3588   \varitem[{$|efp|[k]\equiv E^{\rm f}_+(z^+_k),$}]{The left circularly polarized
 3589     forward traveling field component at $z=z_k$ taken in the $k$th homogeneous
 3590     layer of the discretized grating.}
 3591   \varitem[{$|efm|[k]\equiv E^{\rm f}_-(z^+_k),$}]{The right circularly polarized
 3592     forward traveling field component at $z=z_k$ taken in the $k$th homogeneous
 3593     layer of the discretized grating.}
 3594   \varitem[{$|ebp|[k]\equiv E^{\rm b}_+(z^+_k),$}]{The left circularly polarized
 3595     backward traveling field component at $z=z_k$ taken in the $k$th homogeneous
 3596     layer of the discretized grating.}
 3597   \varitem[{$|ebm|[k]\equiv E^{\rm b}_-(z^+_k),$}]{The right circularly polarized
 3598     backward traveling field component at $z=z_k$ taken in the $k$th homogeneous
 3599     layer of the discretized grating.}
 3600   \medskip
 3601   \noindent
 3602   that is to say, in a loss-less medium in which the nonlinear correction to the
 3603   linear refractive index is determined by the magnitude of the circularly
 3604   polarized components of the field envelopes, these arrays hold the full complex
 3605   spatial evolution of the electric field.
 3606   
 3607   @<Declaration of complex arrays storing the electrical field distribution@>=
 3608     dcomplex *efp,*efm,*ebp,*ebm;
 3609   
 3610   @ Declaration of Boolean variables. The Boolean variables are used as flags
 3611   that internally are set and recognized by the \magbragg\ program, for example
 3612   to determine states or modes of operation as specified by the user via command
 3613   line options.
 3614   In the \magbragg\ program, we use integer variables of |short| precision for
 3615   storing Boolean values, with the value~0 corresponding to the ``false'' state
 3616   and~1 corresponding to the ``true'' state.
 3617   
 3618   @<Declaration of Boolean variables for execution control@>=
 3619      short verbose; /* If nonzero, display information at terminal output during
 3620    program execution */
 3621      short randomdistribution; /* If nonzero, use random layer thicknesses of
 3622    a binary-type grating */
 3623      short writegratingtofile; /* If nonzero, save the grating structure to
 3624        file */
 3625      short scale_stokesparams; /* If nonzero, then scale Stokes parameters by
 3626        |stoke_scalefactor| */
 3627      short normalize_length_to_micrometer; /* If nonzero,  */
 3628      short normalize_intensity; /* If nonzero,  */
 3629      short normalize_ellipticity; /* If nonzero,  */
 3630      short normalize_internally; /* If nonzero,  */
 3631      short odd_layer; /* Keeps track of odd and even grating layers in initialization */
 3632      short chirpflag; /* If nonzero, then apply chirp to periodicity of
 3633          sinusoidal grating structures */
 3634      short apodize; /* If nonzero, apply apodization to the ends of the grating */
 3635      short phasejump; /* If nonzero, apply at least one discrete phase
 3636         discontinuity of the grating profile */
 3637      short fieldevoflag; /* If nonzero, then save spatial field distribution to file */
 3638      short fieldevoflag_efield; /* If nonzero while |fieldevoflag| is nonzero,
 3639        then save the complex electric field as the spatial field distribution */
 3640      short intensityevoflag; /* If nonzero while |fieldevoflag| is nonzero, then
 3641        save the field intensity as the spatial field distribution */
 3642      short fieldevoflag_stoke; /* If nonzero while |fieldevoflag| is nonzero,
 3643        then save the Stokes parameters as the spatial field distribution */
 3644      short intensityinfo; /* If nonzero, then display the maximum and minimum
 3645        field intensities found within the grating at terminal output before
 3646        closing the program */
 3647      short saveintensityinfologfile; /* If nonzero, then also save the displayed
 3648        maximum and minimum intensities to a log file */
 3649      short trmtraject_specified; /* If nonzero,  */
 3650      short save_dbspectra; /* If nonzero, then save any transmission spectrum in
 3651        logarithmic (dB) scale */
 3652      short stokes_parameter_spectrum;/* If nonzero, then save any transmission
 3653        spectrum in terms of the corresponding Stokes parameters */
 3654      short display_surrounding_media; /* If nonzero, then append also the
 3655        surrounding medium when saving the spatial grating profile to file */
 3656      short perturbed_gyration_constant; /* If nonzero,  */
 3657   
 3658   @ Declaration of discretization parameters. These parameters determine the
 3659   discretization of the problem at hand, such as the number of points in
 3660   intensity, ellipticity or wavelength to be scanned.
 3661   The significance of the variables are as follows:\par
 3662   \varitem[|mm|]{The number of points $M$ to be sampled in the spectrum between
 3663     vacuum wavelengths $\lambda_{\rm start}$ and $\lambda_{\rm stop}$.}
 3664   \varitem[|mme|]{The number $M_{\rm e}$ of ellipticities $\varepsilon_{\rm tr}$
 3665     of the transmitted light to be sampled in the interval
 3666     $\varepsilon_{\rm tr,start}\le\varepsilon\le\varepsilon_{\rm tr,stop}$.}
 3667   \varitem[|mmi|]{The number $M_{\rm i}$ of intensities $I_{\rm tr}$ of the
 3668     transmitted light to be sampled in the interval
 3669     $I_{\rm tr,start}\le I_{\rm tr}\le I_{\rm tr,stop}$.}
 3670   
 3671   @<Discretization parameters@>=
 3672      long mm, mme, mmi;
 3673   
 3674   @ Declaration of grating parameters. These parameters fully describe the
 3675   geometry and material properties of the medium in which the wave propagation
 3676   is to be performed. The significance of the variables are as follows:\par
 3677   \varitem[|ll|]{Geometrical length $L$ of the grating measured in metres.}
 3678   \varitem[|nn|]{The number $N$ of discrete interfaces separating the $N-1$
 3679     homogeneous layers of the grating and the surrounding medium.}
 3680   \varitem[|modnum|]{If positive, this is the number of a manually modified
 3681     layer, for instance a defect or cavity layer possessing different geometrical
 3682     or optical properties than the rest of the structure described by any of the
 3683     standard grating options.}
 3684   \varitem[|*z|]{Pointer to an array of $N$ elements for storing the coordinates
 3685     of the discrete interfaces $z_1,\ldots,z_N$ between homogeneous layers of
 3686     the grating.}
 3687   \varitem[|*dz|]{Pointer to an array of $N-1$ elements containing the layer
 3688     thicknesses $|dz|[k]\equiv z_{k+1}-z_k$, $k=1,\ldots,N-1$.}
 3689   \varitem[|*n|, |*g|]{Pointers to arrays of $N-1$ elements containing the
 3690     refractive indices $|n[k]|=n_k$ and magneto-optical gyration coefficients
 3691     $|g[k]|=g_k=i\chi^{({\rm eem})}_{xyz}B^z_0 /(2 n_k)$ of the homogeneous
 3692     layers.}
 3693   \varitem[|*pe|, |*qe|]{Pointers to arrays of $N-1$ elements containing the
 3694     nonlinear optical coefficients
 3695     $|pe[k]|=\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx}$ and
 3696     $|qe[k]|=\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx}$ of the homogeneous
 3697     layers.}
 3698   \varitem[|*pm|, |*qm|]{Pointers to arrays of $N-1$ elements containing the
 3699     nonlinear magneto-optical coefficients
 3700     $|pm[k]|=i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0$ and
 3701     $|qm[k]|=i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0$ of the
 3702     layers.}
 3703   \varitem[|*etafp|, |*etafm|]{Pointers to arrays of $N-1$ elements for storing
 3704     the nonlinear coefficients of propagation $\eta^{\rm f}_+$ related to the
 3705     phase evolution of forward (f) traveling left ($+$) and right ($-$)
 3706     circularly polarized components of in respective layer $z_j<z<z_{j+1}$, with
 3707     $|etafp|[j]=\eta^{\rm f}_+(z^+_j)$ and $|etafm|[j]=\eta^{\rm f}_-(z^+_j)$.}
 3708   \varitem[|*etabp|, |*etabm|]{Analogous to |*etafp| and |*etafm| but instead for
 3709     the nonlinear phase contributions $|etabp|[j]=\eta^{\rm b}_+(z^+_j)$ and
 3710     $|etabm|[j]=\eta^{\rm b}_-(z^+_j)$ for backward traveling field components.}
 3711   \varitem[|*taup|, |*taum|]{Pointers to arrays of $N$ elements for storing the
 3712     forward intra-grating layer transmittances $\tau_{k_+}$ and $\tau_{k_-}$.}
 3713   \varitem[|*taupp|, |*taupm|]{Pointers to arrays of $N$ elements for storing
 3714     the backward intra-grating layer transmittances $\tau'_{k_+}$ and
 3715     $\tau'_{k_-}$.}
 3716   \varitem[|*rhop|, |*rhom|]{Pointers to arrays of $N$ elements for storing the
 3717     forward intra-grating layer reflectances $\rho_{k_+}$ and $\rho_{k_-}$.}
 3718   \varitem[|*rhopp|, |*rhopm|]{Pointers to arrays of $N$ elements for storing the
 3719     backward intra-grating layer reflectances $\rho'_{k_+}$ and $\rho'_{k_-}$.}
 3720   \medskip
 3721   For the definitions of the intra-grating layer reflectances and transmittances,
 3722   see the separate section {\it Calculation of intra-grating layer reflectances}.
 3723   
 3724   @<Grating parameters@>=
 3725      long nn, modnum;
 3726      double ll,*z,*dz,*n,*g,*pe,*pm,*qe,*qm,*etafp,*etafm,*etabp,*etabm;
 3727      double *taup,*taum,*taupp,*taupm,*rhop,*rhom,*rhopp,*rhopm;
 3728   
 3729   @ Declaration of file pointers.
 3730   
 3731   @<Declaration of file pointers@>=
 3732      FILE *fp_s0,*fp_s1,*fp_s2,*fp_s3; /* Stokes parameters of incident wave  */
 3733      FILE *fp_v0,*fp_v1,*fp_v2,*fp_v3; /* Stokes parameters of reflected wave */
 3734      FILE *fp_w0,*fp_w1,*fp_w2,*fp_w3; /* Stokes params. of transmitted wave  */
 3735      FILE *fp_evo=NULL,*fp_ievo=NULL,*fp_spec=NULL,*fp_traject=NULL;
 3736      FILE *fp_irspec=NULL,*fp_itspec=NULL,*fp_icspec=NULL,*fp_gr=NULL;
 3737      FILE *fp_evo_s0=NULL,*fp_evo_s1=NULL,*fp_evo_s2=NULL,*fp_evo_s3=NULL;
 3738      FILE *intensinfologfile=NULL;
 3739   
 3740   @ Declaration of character strings holding file names.
 3741   Generally in this program, the maximum number of characters a file name
 3742   string can contain is |NCHMAX|, as defined in the definitions section
 3743   of the program.
 3744   
 3745   @<Declaration of strings and file names@>=
 3746      char gratingtype[NCHMAX],gratingsubtype[NCHMAX];
 3747      char fieldevofilename[NCHMAX],intensityevofilename[NCHMAX];
 3748      char spectrumfilename[NCHMAX],trmtraject_filename[NCHMAX];
 3749      char intensity_reflection_spectrumfilename[NCHMAX],
 3750           intensity_transmission_spectrumfilename[NCHMAX],
 3751           intensity_check_spectrumfilename[NCHMAX];
 3752      char fieldevofilename_s0[NCHMAX],fieldevofilename_s1[NCHMAX],
 3753           fieldevofilename_s2[NCHMAX],fieldevofilename_s3[NCHMAX];
 3754      char intensinfologfilename[NCHMAX];
 3755      char outfilename[NCHMAX],gratingfilename[NCHMAX];
 3756      char outfilename_s0[NCHMAX],outfilename_s1[NCHMAX],
 3757           outfilename_s2[NCHMAX],outfilename_s3[NCHMAX];
 3758      char outfilename_v0[NCHMAX],outfilename_v1[NCHMAX],
 3759           outfilename_v2[NCHMAX],outfilename_v3[NCHMAX];
 3760      char outfilename_w0[NCHMAX],outfilename_w1[NCHMAX],
 3761           outfilename_w2[NCHMAX],outfilename_w3[NCHMAX];
 3762   
 3763   @ Declaration of dummy variables. Here dummy and temporary variables are
 3764   declared, where the ``dummy'' variables typically are integer counters
 3765   for iteration over wavelength, ellipticity, intensity and so on, while the
 3766   temporary variables are internally used for in some cases saving computational
 3767   time, and also for the sake of increasing the readability of the program
 3768   somewhat.
 3769   
 3770   @<Declaration of local dummy variables@>=
 3771      dcomplex tmpfp,tmpfm,tmpbp,tmpbm;
 3772      double tmp,zt,s0,s1,s2,s3,v0,v1,v2,v3,w0,w1,w2,w3,stn,
 3773         maxintens=0.0,maxintens_inintens=0.0,maxintens_inellip=0.0,
 3774         maxintens_trintens=0.0,maxintens_trellip=0.0;
 3775      int no_arg,status=0,tmpch;
 3776      long j,k,ke,ki;
 3777   
 3778   @*Initialization of variables.
 3779   
 3780   @<Initialize variables@>=
 3781      trmtraject_specified=0; /* Is a trajectory of $(W_0,W_3)$ specified? */
 3782      intensityinfo=0; /* Printing basic intensity info to stdout; default: off */
 3783      saveintensityinfologfile=0; /* Printing basic intensity info to file */
 3784      randomdistribution=0; /* Random shuffling of layers; default: off */
 3785      writegratingtofile=0; /* Save spatial grating structure; default: off */
 3786      scale_stokesparams=0; /* Scale Stokes parameters by |stoke_scalefactor|; default: off */
 3787      stoke_scalefactor=1.0; /* Scale factor to be used for Stokes parameters */
 3788      normalize_length_to_micrometer=0;
 3789      normalize_intensity=0;/* Write normalized intensity to file; default: off */
 3790      normalize_ellipticity=0;/* Ditto for the ellipticity */
 3791      ranseed=1097; /* Seed for random number generator */
 3792      modnum=-1;  /* If positive, the manually modified layer number */
 3793      verbose=0;  /* Verbose mode is off by default */
 3794      apodize=0;  /* Apodization is off by default */
 3795      phasejump=0;  /* Discrete phase jump is off by default */
 3796      normalize_internally=0; /* Default state of internal normalization is off */
 3797      odd_layer=0; /* Counter flag for odd and even grating layers */
 3798      chirpflag=1;
 3799      save_dbspectra=0;
 3800      stokes_parameter_spectrum=0;
 3801      display_surrounding_media=1; /* Append also the
 3802        surrounding medium when saving the spatial grating profile to file;
 3803        default: on */
 3804      perturbed_gyration_constant=0;
 3805      fieldevoflag=0; /* Save spatial field distribution to file; default: off */
 3806      fieldevoflag_efield=0; /* Save as complex electric field; default: off */
 3807      fieldevoflag_stoke=0; /* Save as Stokes parameters; default: off */
 3808      intensityevoflag=0; /* Save spatial intensity distribution; default: off */
 3809      mm=mmdef; /* Number of sampling points in optical spectrum */
 3810      nn=nndef; /* Number of layer interfaces of grating; num of layers is nn-1 */
 3811      mme=mmedef; /* Number of sampling points in transmitted ellipticity */
 3812      mmi=mmidef; /* Number of sampling points in transmitted intensity */
 3813      nne=1; /* Default number extra, intra-layer sampling points */
 3814      ll=lldef; /* Default physical length of the grating structure */
 3815      lambdastart=lambdastartdef;
 3816      lambdastop=lambdastopdef;
 3817      phasejumpangle=0.0;  /* Discrete phase jump is off by default */
 3818      phasejumpposition=0.0;  /* Discrete phase jump is off by default */
 3819      phi=0.0;  /* Discrete phase jump is off by default */
 3820      nsurr=nsurrdef; /* Default index of refraction of the surrounding medium */
 3821      strcpy(outfilename,"out.stok");          /* Default output file basename */
 3822      strcpy(fieldevofilename,"out.fevo.dat"); /* Default output file basename */
 3823      strcpy(fieldevofilename_s0,"out.fevo.s0.dat");
 3824      strcpy(fieldevofilename_s1,"out.fevo.s1.dat");
 3825      strcpy(fieldevofilename_s2,"out.fevo.s2.dat");
 3826      strcpy(fieldevofilename_s3,"out.fevo.s3.dat");
 3827      strcpy(spectrumfilename,"out.rsp.dat");  /* Default output file name */
 3828      strcpy(intensity_reflection_spectrumfilename,"out.irsp.dat");
 3829      strcpy(intensity_transmission_spectrumfilename,"out.trsp.dat");
 3830      strcpy(intensity_check_spectrumfilename,"out.chec.dat");
 3831      fp_s0=NULL; fp_s1=NULL; fp_s2=NULL; fp_s3=NULL;
 3832      fp_v0=NULL; fp_v1=NULL; fp_v2=NULL; fp_v3=NULL;
 3833      fp_w0=NULL; fp_w1=NULL; fp_w2=NULL; fp_w3=NULL;
 3834   
 3835   @*Memory allocation.
 3836   Allocate memory for the temporary storage of the spatial distribution of
 3837   material parameters of the grating structure and internal, complex-valued
 3838   electromagnetic fields.
 3839   In \TeX-style notation, the parameters are interpreted in terms
 3840   of the optical and magneto-optical susceptibilities [Fredrik Jonsson,
 3841   {\it The Nonlinear Optics of Magneto-Optic Media}, PhD thesis
 3842   (The Royal Institute of Technology, Stockholm, 2000)] as follows,
 3843   starting with the all-optical (electric-dipolar related) parameters
 3844   $$
 3845     \eqalign{
 3846       |n[k]|&=n_k=[1+\chi^{({\rm ee})}_{xx}]^{1/2},\cr
 3847       |pe[k]|
 3848         &=\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx},\cr
 3849       |qe[k]|
 3850         &=\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx},\cr
 3851     }
 3852   $$
 3853   where all susceptibilities of the right-hand sides are to be evaluated in the
 3854   domains $z_k<z<z_{k+1}$, $k=1,2,\ldots N-1$. In addition to the all-optical
 3855   parameters, the magneto-optical (magnetic-dipolar related) parameters are
 3856   defined as
 3857   $$
 3858     \eqalign{
 3859       |g[k]|&=g_k=i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n_k),\cr
 3860       |pm[k]|
 3861         &=i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
 3862       |qm[k]|
 3863         &=i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
 3864     }
 3865   $$
 3866   using the same conventions of evaluation for the involved susceptibilities in
 3867   the righ-hand sides.
 3868   With these definitions, the left circularly polarized (LCP) and right
 3869   circularly polarized (RCP) modes that propagate in the forward direction in
 3870   the $k$th layer will experience the linear, field-independent refractive
 3871   indices $n_{k_+}$ and $n_{k_-}$, respectively, with
 3872   $$
 3873     \eqalignno{
 3874       n_{k_+}&=n_k[1+i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n^2_k)]
 3875               =n_k+g_k,&{\rm(LCP)}\cr
 3876       n_{k_-}&=n_k[1-i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n^2_k)]
 3877               =n_k-g_k.&{\rm(RCP)}\cr
 3878     }
 3879   $$
 3880   For backward propagating light, the experienced indices of refraction are
 3881   reversed, that is to say, backward propagating left circularly polarized
 3882   light experience $n_-$ as the refractive index, while the right circularly
 3883   polarized experience $n_+$.
 3884   
 3885   We here throughout adopt to common standard definition of circularly polarized
 3886   light, that when looking into an oncoming wave propagating in the positive
 3887   $z$-direction, the vector of the LCP electric field component $E^{\rm f}_+$
 3888   of the wave describes counterclockwise motion, while it for the RCP field
 3889   component $E^{\rm f}_-$ instead describes clockwise motion.
 3890   This convention conforms to the classical one as used in
 3891   optics~[J.~D.~Jackson, {Classical Electrodynamics} (Wiley, New York, 1975);
 3892   M.~Born and E.~Wolf, {Principles of Optics} (Cambridge University Press,
 3893   Cambridge, 1980)].
 3894   Similarly, by looking into an oncoming wave propagating in the negative
 3895   $z$-direction, the vector of the LCP electric field component $E^{\rm b}_+$
 3896   describes counterclockwise motion, while it for the RCP field component
 3897   $E^{\rm b}_-$ describes clockwise motion.
 3898   
 3899   In the following allocation of memory, the $k$th element of respective vector
 3900   contains the numerical value for the respective material parameter evaluated
 3901   in the domain $z_k < z < z_{k+1}$, for $k=1,2,\ldots,N-1$, while the vectors
 3902   containing the electrical field components contain the respective component
 3903   evaluated at the ``beginning'' of respective layer, at $z=z^+_k$.
 3904   From material parameters such as the linear refractive indices $n_k$ and
 3905   the magneto-optical gyration constants $g_k$ of the compound structure,
 3906   derived numerical quantities, such as the transmission coefficients
 3907   $\tau_{k_{\pm}}$ and $\tau'_{k_{\pm}}$ and the reflection coefficients
 3908   $\rho_{k_{\pm}}$ and $\rho'_{k_{\pm}}$ across the interfaces at $z_k$,
 3909   are later on calculated and stored in vectors that here are allocated.
 3910   
 3911   @<Allocate optical field vectors@>=
 3912   {
 3913      z=dvector(1,nn);     /* Spatial coordinate $z_k$ along the Bragg grating */
 3914      dz=dvector(1,nn-1);  /*$|dz|[k]\equiv|z|[k+1]-|z|[k]$, $k=1,2,...,|nn|-1$*/
 3915      efp=dcvector(0,nn);  /* Equals $E^f_{k_+}$ in \TeX-style notation    */
 3916      efm=dcvector(0,nn);  /* Equals $E^f_{k_-}$ in \TeX-style notation    */
 3917      ebp=dcvector(0,nn);  /* Equals $E^b_{k_+}$ in \TeX-style notation    */
 3918      ebm=dcvector(0,nn);  /* Equals $E^b_{k_-}$ in \TeX-style notation    */
 3919      taup=dvector(1,nn);  /* Forward LCP transmission coefficient $\tau_{k_+}$ */
 3920      taum=dvector(1,nn);  /* Forward RCP transmission coefficient $\tau_{k_+}$ */
 3921      taupp=dvector(1,nn); /* Backward LCP transmission coeff.~ $\tau'_{k_+}$ */
 3922      taupm=dvector(1,nn); /* Backward RCP transmission coeff.~$\tau'_{k_-}$ */
 3923      rhop=dvector(1,nn);  /* Forward LCP reflection coeff.~$\rho_{k_+}$ */
 3924      rhom=dvector(1,nn);  /* Forward RCP reflection coeff.~$\rho_{k_-}$ */
 3925      rhopp=dvector(1,nn); /* Backward LCP reflection coeff.~$\rho'_{k_+}$ */
 3926      rhopm=dvector(1,nn); /* Backward RCP reflection coeff.~$\rho'_{k_-}$ */
 3927      n=dvector(0,nn);     /* Linear electric-dipolar refractive index $n(z)$ */
 3928      g=dvector(0,nn);     /* Linear magneto-optical contribution to $n(z)$ */
 3929      pe=dvector(1,nn-1);  /* Nonlinear all-optical contribution to $n(z)$ */
 3930      pm=dvector(1,nn-1);  /* Nonlinear magneto-optical contribution to $n(z)$ */
 3931      qe=dvector(1,nn-1);  /* Nonlinear all-optical contribution to $n(z)$ */
 3932      qm=dvector(1,nn-1);  /* Nonlinear magneto-optical contribution to $n(z)$ */
 3933      etafp=dvector(1,nn-1); /* Nonlinear LCP forward contribution to $n(z)$  */
 3934      etabp=dvector(1,nn-1); /* Nonlinear LCP backward contribution to $n(z)$ */
 3935      etafm=dvector(1,nn-1); /* Nonlinear RCP forward contribution to $n(z)$  */
 3936      etabm=dvector(1,nn-1); /* Nonlinear RCP backward contribution to $n(z)$ */
 3937   }
 3938   
 3939   @ At the end of the program, we would also like to properly deallocate
 3940   the memory occupied by the previously allocated real- and complex-valued
 3941   vectors that have been used in the simulation. This is done by executing
 3942   the following block.
 3943   
 3944   @<Deallocate optical field vectors@>=
 3945   {
 3946      free_dcvector(efp,0,nn);
 3947      free_dcvector(efm,0,nn);
 3948      free_dcvector(ebp,0,nn);
 3949      free_dcvector(ebm,0,nn);
 3950      free_dvector(taup,1,nn);
 3951      free_dvector(taum,1,nn);
 3952      free_dvector(taupp,1,nn);
 3953      free_dvector(taupm,1,nn);
 3954      free_dvector(rhop,1,nn);
 3955      free_dvector(rhom,1,nn);
 3956      free_dvector(rhopp,1,nn);
 3957      free_dvector(rhopm,1,nn);
 3958      free_dvector(n,0,nn);
 3959      free_dvector(g,0,nn);
 3960      free_dvector(pe,1,nn-1);
 3961      free_dvector(pm,1,nn-1);
 3962      free_dvector(qe,1,nn-1);
 3963      free_dvector(qm,1,nn-1);
 3964      free_dvector(etafp,1,nn-1);
 3965      free_dvector(etabp,1,nn-1);
 3966      free_dvector(etafm,1,nn-1);
 3967      free_dvector(etabm,1,nn-1);
 3968      if (trmtraject_specified) {
 3969         free_dvector(w0traj,1,mmtraject);
 3970         free_dvector(w3traj,1,mmtraject);
 3971      }
 3972   }
 3973   
 3974   @*Initialization of the grating structure.
 3975   Using the previously allocated memory for the temporary storage of the
 3976   spatially distributed grating structure, initiate the material parameters
 3977   of the interior of the grating.
 3978   If the user via the command line options has specified that a perturbation
 3979   of the gyration constant should be present somewhere along the grating, then
 3980   add a perturbation in the functional form of a magneto-optical effect that
 3981   would arise due to a current carrying wire, placed orthogonal to the direction
 3982   of propagation, and in a close vicinity of the medium.
 3983   
 3984   @<Initiate grating structure@>=
 3985   {
 3986      if(!strcmp(gratingtype,"stepwise")) {
 3987         @<Initiate binary grating structure@>;
 3988      } else if(!strcmp(gratingtype,"sinusoidal")) {
 3989         @<Initiate sinusoidal grating structure@>;
 3990      } else if(!strcmp(gratingtype,"chirped")) {
 3991         @<Initiate chirped grating structure@>;
 3992      } else if(!strcmp(gratingtype,"fractal")) {
 3993         @<Initiate fractal grating structure@>;
 3994      } else{
 3995         fprintf(stderr,
 3996            "%s: Error: Specified grating type is invalid.\n",progname);
 3997         showsomehelp();
 3998         exit(FAILURE);
 3999      }
 4000      if (perturbed_gyration_constant) {
 4001         @<Add perturbation of gyration constant along grating structure@>;
 4002      }
 4003   }
 4004   
 4005   @ For the binary type of stepwise gratings, with the refractive index and
 4006   all other material parameters of the medium spatially alternating between
 4007   two distinct values, the odd layers (i.e. $z_k<z<z_{k+1}$, with $k$ being
 4008   an odd integer) have all the layer thickness given by the parameter |t1|,
 4009   while all even layers (i.e. $z_k<z<z_{k+1}$, with $k$ being an even integer)
 4010   have the layer thickness given by |t2|.
 4011   This means that in this case the total length of the grating is given as
 4012   $$
 4013     L = \{{\rm the\ number\ of\ odd\ layers}\}\times|t1|
 4014          + \{{\rm the\ number\ of\ even\ layers}\}\times|t2|,
 4015   $$
 4016   and hence the value of any specified grating length (by using the
 4017   \.{--gratinglength} option) will be neglected for the \.{twolevel}
 4018   stepwise type of grating.
 4019   
 4020   The material parameters |pe|, |qe|, |pm|, and |qm|, are (as previously)
 4021   defined as
 4022   $$
 4023     \eqalign{
 4024       |pe[k]|&=\chi^{\rm eeee}_{xxxx}(-\omega;\omega,\omega,-\omega)
 4025         -\chi^{\rm eeee}_{xyyx}(-\omega;\omega,\omega,-\omega),\cr
 4026       |qe[k]|&=\chi^{\rm eeee}_{xxxx}(-\omega;\omega,\omega,-\omega)
 4027         +\chi^{\rm eeee}_{xyyx}(-\omega;\omega,\omega,-\omega),\cr
 4028       |pm[k]|&=i(\chi^{\rm eeeem}_{xyyyz}(-\omega;\omega,\omega,-\omega,0)
 4029         -\chi^{\rm eeeem}_{xxxyz}(-\omega;\omega,\omega,-\omega,0))B^z_0,\cr
 4030       |qm[k]|&=i(\chi^{\rm eeeem}_{xyyyz}(-\omega;\omega,\omega,-\omega,0)
 4031         +\chi^{\rm eeeem}_{xxxyz}(-\omega;\omega,\omega,-\omega,0))B^z_0,\cr
 4032     }
 4033   $$
 4034   where $\chi^{\rm eeee}_{\mu\alpha\beta\gamma}
 4035   (-\omega;\omega,\omega,-\omega)$ and
 4036   $\chi^{\rm eeeem}_{\mu\alpha\beta\gamma\delta}
 4037   (-\omega;\omega,\omega,-\omega,0)$
 4038   are the nonlinear optical and magneto-optical susceptibility tensors
 4039   governing the intensity-dependent refractive index and Faraday effect,
 4040   respectively, taken in a notation conforming to P.~N.~Butcher and D.~Cotter
 4041   [P.~N.~Butcher and D.~Cotter, {\it The Elements of Nonlinear Optics}
 4042   (Cambridge University Press, New York, 1990)], and to be evaluated in
 4043   respective layer $z_k<z<z_{k+1}$, $k=1,2,\ldots,N-1$.
 4044   
 4045   When initializing the binary type of stepwise gratings, the program will check
 4046   if the |randomdistribution| flag (a numerical integer) was set through the
 4047   command line parameters. If so (i.~e.~if $|randomdistribution|=1$), then the
 4048   layers of different indices and material parameters will be randomly ordered.
 4049   
 4050   @<Initiate binary grating structure@>=
 4051   {
 4052      if(!strcmp(gratingsubtype,"twolevel")) {
 4053         if (randomdistribution) {
 4054            for (j=1;j<=nn-1;j++) {
 4055               if (j==modnum) {
 4056                  if (j==1) z[j]=0.0;
 4057                  z[j+1]=z[j]+modt1;
 4058                  dz[j]=modt1;
 4059                  n[j]=modn1;
 4060                  g[j]=modg1;
 4061                  pe[j]=modpe1;
 4062                  pm[j]=modpm1;
 4063                  qe[j]=modqe1;
 4064                  qm[j]=modqm1;
 4065               } else {
 4066                  ranseed=ranseed+j;
 4067                  if (ran1(&ranseed)>0.5) {
 4068                     if (verbose) fprintf(stdout,"Random number: 1\n");
 4069                     if (j==1) z[j]=0.0;
 4070                     z[j+1]=z[j]+t1;
 4071                     dz[j]=t1;
 4072                     n[j]=n1;
 4073                     g[j]=g1;
 4074                     pe[j]=pe1;
 4075                     pm[j]=pm1;
 4076                     qe[j]=qe1;
 4077                     qm[j]=qm1;
 4078                  } else {
 4079                     if (verbose) fprintf(stdout,"Random number: 0\n");
 4080                     if (j==1) z[j]=0.0;
 4081                     z[j+1]=z[j]+t2;
 4082                     dz[j]=t2;
 4083                     n[j]=n2;
 4084                     g[j]=g2;
 4085                     pe[j]=pe2;
 4086                     pm[j]=pm2;
 4087                     qe[j]=qe2;
 4088                     qm[j]=qm2;
 4089                  }
 4090               }
 4091            }
 4092         } else { /* else, if non-random distribution */
 4093            if (modnum<0) { /* if no modified layer of the grating, ... */
 4094               for (j=1;j<=nn-1;j=j+2) { /* all odd layers, $|j|=1,3,5,\ldots$ */
 4095                  z[j]=0.5*((double)(j-1))*(t1+t2);
 4096                  dz[j]=t1;
 4097                  n[j]=n1;
 4098                  g[j]=g1;
 4099                  pe[j]=pe1;
 4100                  pm[j]=pm1;
 4101                  qe[j]=qe1;
 4102                  qm[j]=qm1;
 4103                  if (j==nn-1) z[nn]=z[nn-1]+t1;
 4104               }
 4105               for (j=2;j<=nn-1;j=j+2) { /* all even layers, $|j|=2,4,6,\ldots$ */
 4106                  z[j]=z[j-1]+t1;
 4107                  dz[j]=t2;
 4108                  n[j]=n2;
 4109                  g[j]=g2;
 4110                  pe[j]=pe2;
 4111                  pm[j]=pm2;
 4112                  qe[j]=qe2;
 4113                  qm[j]=qm2;
 4114                  if (j==nn-1) z[nn]=z[nn-1]+t2;
 4115               }
 4116            } else { /* ... else, if at least one modified layer of the grating */
 4117               for (j=1;j<=nn-1;j++) {
 4118                  if (j==1) z[j]=0.0;
 4119                  if (j==modnum) { /* the modified layer */
 4120                     z[j+1]=z[j]+modt1;
 4121                     dz[j]=modt1;
 4122                     n[j]=modn1;
 4123                     g[j]=modg1;
 4124                     pe[j]=modpe1;
 4125                     pm[j]=modpm1;
 4126                     qe[j]=modqe1;
 4127                     qm[j]=modqm1;
 4128                  } else {
 4129                     tmp=((double)j)/((double)2);
 4130                     if (tmp-floor(tmp)>0.25) { /* if |j| odd */
 4131                        z[j+1]=z[j]+t1;
 4132                        dz[j]=t1;
 4133                        n[j]=n1;
 4134                        g[j]=g1;
 4135                        pe[j]=pe1;
 4136                        pm[j]=pm1;
 4137                        qe[j]=qe1;
 4138                        qm[j]=qm1;
 4139                     } else { /* if |j| even */
 4140                        z[j+1]=z[j]+t2;
 4141                        dz[j]=t2;
 4142                        n[j]=n2;
 4143                        g[j]=g2;
 4144                        pe[j]=pe2;
 4145                        pm[j]=pm2;
 4146                        qe[j]=qe2;
 4147                        qm[j]=qm2;
 4148                     }
 4149                  }
 4150               }
 4151            }
 4152         }
 4153      } else{
 4154         fprintf(stderr,"%s: Error.\n",progname);
 4155         fprintf(stderr,"%s: (No valid grating subtype found).\n",progname);
 4156         exit(FAILURE);
 4157      }
 4158   }
 4159   
 4160   @ For the sinusoidal type gratings, the grating structure is spatially
 4161   oversampled and modelled as a large number of thin homogeneous slices,
 4162   as in the oversampling in some algorithms for calculation of
 4163   transmission properties of fiber Bragg gratings. In the oversampling,
 4164   the thickness of each of the layers is equal, using an equidistanly
 4165   spaced spatial increment in the beam propagation performed across each
 4166   of the layers.
 4167   Here, |nper| is the physical, spatial period of the refractive index
 4168   distribution $n(z)$, while |gper| is the spatial period of the linear
 4169   magneto-optical gyration constant $g(z)$, etc.
 4170   
 4171   For sinusoidal type gratings, any stated apodization profile will also
 4172   be applied,
 4173   in order to get rid of any occurring Gibbs oscillations due to a rapid
 4174   change of the index modulation at the ends of the grating.
 4175   From a user perspective, the \.{--apodize}
 4176   option is used at startup time of the program for specifying a smoother
 4177   transition between modulated and non-modulated regions of the grating.
 4178   The apodization is performed at the ends of the grating according to a
 4179   multiplicative factor of the |n2| and |g2| modulation amplitudes of the
 4180   refractive index and gyration coefficient, of the form
 4181   $$
 4182     f(z)=\Bigg\lbrace
 4183       \matrix{[1-\cos(\pi z/a)]/2,&\ 0\le z\le a,\cr
 4184               1,&\ a<z<L-a,\cr
 4185               [1-\cos(\pi(z-L)/a)]/2,&\ L-a\le z\le L,}
 4186   $$
 4187   and otherwise $f(z)=0$, for any $z$ outside the above domains of definition,
 4188   where $a$ is the effective apodization length, being the floating point
 4189   parameter specified after the \.{--apodize} option, and $L$ as usual the
 4190   geometrical overall length of the grating.
 4191   
 4192   In the generation of the sinusoidal grating structure, we also include any
 4193   possible discrete spatial phase jump, as specified by the \.{--phasejump}
 4194   command line option.
 4195   
 4196   @<Initiate sinusoidal grating structure@>=
 4197   {
 4198      t1=ll/((double)(nn-1));
 4199      for (j=1;j<=nn-1;j++) {
 4200         z[j]=((double)(j-1))*t1;
 4201         dz[j]=t1;
 4202         if (apodize) {
 4203            if ((0.0<=z[j])&&(z[j]<=apolength)) {
 4204               tmp=(1.0-cos(pi*z[j]/apolength))/2.0;
 4205            } else if ((apolength<=z[j])&&(z[j]<=ll-apolength)) {
 4206               tmp=1.0;
 4207            } else if ((ll-apolength<=z[j])&&(z[j]<=ll)) {
 4208               tmp=(1.0-cos(pi*(z[j]-ll)/apolength))/2.0;
 4209            } else {
 4210               tmp=0.0;
 4211               fprintf(stderr,
 4212                  "%s: Impossible apodization event occurred.",progname);
 4213               fprintf(stderr,
 4214                  "%s: (Please check grating initialization.)",progname);
 4215            }
 4216         }
 4217         if (phasejump) {
 4218            if (z[j]>=phasejumpposition) {
 4219               phi=phasejumpangle;
 4220            } else {
 4221               phi=0.0;
 4222            }
 4223         }
 4224         if (apodize) {
 4225            n[j]=n1+n2*tmp*sin(twopi*z[j]/nper+phi);
 4226            g[j]=g1+g2*tmp*sin(twopi*z[j]/gper+phi);
 4227         } else {
 4228            n[j]=n1+n2*sin(twopi*z[j]/nper+phi);
 4229            g[j]=g1+g2*sin(twopi*z[j]/gper+phi);
 4230         }
 4231         pe[j]=pe1+pe2*sin(twopi*z[j]/peper);
 4232         pm[j]=pm1+pm2*sin(twopi*z[j]/pmper);
 4233         qe[j]=qe1+qe2*sin(twopi*z[j]/qeper);
 4234         qm[j]=qm1+qm2*sin(twopi*z[j]/qmper);
 4235      }
 4236      z[nn]=ll;
 4237   }
 4238   
 4239   @ Just as for the sinusoidal type gratings, the chirped grating structure
 4240   is spatially oversampled and modelled as a large number of thin homogeneous
 4241   slices of equal thickness.
 4242   As in the case of a pure sinusoidal grating, we here also check whether an
 4243   apodization should be applied to the grating profile, subsequently applying
 4244   the apodization.
 4245   In the generation of the chirped grating structure, we also include any
 4246   possible discrete spatial phase jump, as specified by the \.{--phasejump}
 4247   command line option.
 4248   
 4249   @<Initiate chirped grating structure@>=
 4250   {
 4251      t1=ll/((double)(nn-1));
 4252      for (j=1;j<=nn-1;j++) {
 4253         z[j]=((double)(j-1))*t1;
 4254         dz[j]=t1;
 4255         if (apodize) {
 4256            if ((0.0<=z[j])&&(z[j]<=apolength)) {
 4257               tmp=(1.0-cos(pi*z[j]/apolength))/2.0;
 4258            } else if ((apolength<=z[j])&&(z[j]<=ll-apolength)) {
 4259               tmp=1.0;
 4260            } else if ((ll-apolength<=z[j])&&(z[j]<=ll)) {
 4261               tmp=(1.0-cos(pi*(z[j]-ll)/apolength))/2.0;
 4262            } else {
 4263               tmp=0.0;
 4264               fprintf(stderr,
 4265                  "%s: Impossible apodization event occurred.",progname);
 4266               fprintf(stderr,
 4267                  "%s: (Please check grating initialization.)",progname);
 4268            }
 4269         }
 4270         if (phasejump) {
 4271            if (z[j]>=phasejumpposition) {
 4272               phi=phasejumpangle;
 4273            } else {
 4274               phi=0.0;
 4275            }
 4276         }
 4277         if (apodize) {
 4278            if (fabs(ncrp)>0.0) /* if nonzero chirp of $n(z)$ */
 4279               n[j]=n1+n2*tmp*sin((twopi/ncrp)*log(1.0+ncrp*z[j]/nper)+phi);
 4280            else
 4281               n[j]=n1+n2*tmp*sin(twopi*z[j]/nper+phi);
 4282            if (fabs(gcrp)>0.0) /* if nonzero chirp of $g(z)$ */
 4283               g[j]=g1+g2*tmp*sin((twopi/gcrp)*log(1.0+gcrp*z[j]/gper)+phi);
 4284            else
 4285               g[j]=g1+g2*tmp*sin(twopi*z[j]/gper+phi);
 4286         } else {
 4287            if (fabs(ncrp)>0.0) /* if nonzero chirp of $n(z)$ */
 4288               n[j]=n1+n2*sin((twopi/ncrp)*log(1.0+ncrp*z[j]/nper)+phi);
 4289            else
 4290               n[j]=n1+n2*sin(twopi*z[j]/nper+phi);
 4291            if (fabs(gcrp)>0.0) /* if nonzero chirp of $g(z)$ */
 4292               g[j]=g1+g2*sin((twopi/gcrp)*log(1.0+gcrp*z[j]/gper)+phi);
 4293            else
 4294               g[j]=g1+g2*sin(twopi*z[j]/gper+phi);
 4295         }
 4296         if (fabs(pecrp)>0.0) /* if nonzero chirp of $p_{\rm e}(z)$ */
 4297            pe[j]=pe1+pe2*sin((twopi/pecrp)*log(1.0+pecrp*z[j]/peper));
 4298         else
 4299            pe[j]=pe1+pe2*sin(twopi*z[j]/peper);
 4300         if (pmcrp*pmcrp>0.0) /* if nonzero chirp of $p_{\rm m}(z)$ */
 4301            pm[j]=pm1+pm2*sin((twopi/pmcrp)*log(1.0+pmcrp*z[j]/pmper));
 4302         else
 4303            pm[j]=pm1+pm2*sin(twopi*z[j]/pmper);
 4304         if (fabs(qecrp)>0.0) /* if nonzero chirp of $q_{\rm e}(z)$ */
 4305            qe[j]=qe1+qe2*sin((twopi/qecrp)*log(1.0+qecrp*z[j]/qeper));
 4306         else
 4307            qe[j]=qe1+qe2*sin(twopi*z[j]/qeper);
 4308         if (fabs(qmcrp)>0.0) /* if nonzero chirp of $q_{\rm m}(z)$ */
 4309            qm[j]=qm1+qm2*sin((twopi/qmcrp)*log(1.0+qmcrp*z[j]/qmper));
 4310         else
 4311            qm[j]=qm1+qm2*sin(twopi*z[j]/qmper);
 4312      }
 4313      z[nn]=ll;
 4314   }
 4315   
 4316   @ For the fractal type gratings, the grating structure is composed of a
 4317   self-similar structure with certain scaling properties.
 4318   Currently only the Cantor-type fractal is possible to apply to the grating
 4319   structure.
 4320   
 4321   The initialization of the Cantor-type grating is performed by one single call
 4322   to |init_cantor_fractal_grating()|, which intiates the positions $z_k$ at
 4323   which the interfaces between media of different properties are located.
 4324   The |init_cantor_fractal_grating()| routine then makes recursive calls to
 4325   itself, until the bottom level of the fractal initialization is reached.
 4326   After this, the material parameters of these regions are set sequentially
 4327   in the same way as for binary type gratings.
 4328   
 4329   In the initialization of the Cantor-type fractal grating, the program uses
 4330   the vector |z[1..N]| with upper bound determined by the `level' $p$ of the
 4331   fractal as $N=2^p$. The value of $N$ is calculated and set immediately after
 4332   the program has parsed the level from the command line options, and hence
 4333   any additional specifications of $N$ are superfluous, as this is set by the
 4334   fractal level.
 4335   If the number of elements in |z| is {\sl not} an integer power of two, then
 4336   the call to |init_cantor_fractal_grating()| will fail, leaving the error
 4337   message of this routine on exit.
 4338   This will happen if, for example, a command line option specifying $N$ appears
 4339   after the specification of the fractal type grating, if the specified value
 4340   for $N$ does not conform with the convention that $N=2^p$.
 4341   
 4342   @<Initiate fractal grating structure@>=
 4343   {
 4344      tmp=1.0;
 4345      for (j=1;j<=fractal_level-1;j++) tmp=2.0*tmp;
 4346      for (j=1;j<=maximum_fractal_level-fractal_level;j++) tmp=3.0*tmp;
 4347      /* leaves $|tmp|=2^(p-1)3^(p_{\rm max}-p)$ */
 4348      ll=tmp*t1-tmp*t2;
 4349      tmp=1.0;
 4350      for (j=1;j<=maximum_fractal_level-1;j++) tmp=3.0*tmp;
 4351      ll=ll+tmp*t2;
 4352      if (verbose) {
 4353         fprintf(stdout,"%s: Minimum layer thickness at maximum recursion depth:\n",
 4354            progname);
 4355         fprintf(stdout,"%s:     t2=%f [nm]\n",progname,t1*1.0e9);
 4356         fprintf(stdout,"%s:     t2=%f [nm]\n",progname,t2*1.0e9);
 4357         fprintf(stdout,"%s: Fractal grating length calculated as L=%e [m]\n",
 4358            progname,ll);
 4359         fprintf(stdout,
 4360            "%s: Based on fractal recursion of %d out of a maximum of %d levels.\n",
 4361            progname,fractal_level,maximum_fractal_level);
 4362      }
 4363      init_cantor_fractal_grating(z,1,nn,0.0,ll,n1,n2);
 4364      for (j=1;j<=nn-1;j++) {
 4365         dz[j]=z[j+1]-z[j];
 4366         if (j==1) {
 4367            odd_layer=1;
 4368         } else {
 4369            odd_layer=(odd_layer?0:1);
 4370         }
 4371         n[j]=(odd_layer?n1:n2);
 4372         g[j]=(odd_layer?g1:g2);
 4373         pe[j]=(odd_layer?pe1:pe2);
 4374         pm[j]=(odd_layer?pm1:pm2);
 4375         qe[j]=(odd_layer?qe1:qe2);
 4376         qm[j]=(odd_layer?qm1:qm2);
 4377      }
 4378   }
 4379   
 4380   @ Adding any present perturbation of gyration constant.
 4381   If the user via the command line has specified that a perturbation of the
 4382   gyration constant should be added to the present spatial distribution,
 4383   then |perturbed_gyration_constant| will be set to unity (true), and a
 4384   perturbation of the profile corresponding to the magnetic field strength
 4385   of a current carrying wire, orthogonal to the direction of propagation of
 4386   light, will be added.
 4387   The added perturbation $\Delta g(z)$ will be a ``bump'' of the Lorentzian
 4388   spatial shape
 4389   $$
 4390     \Delta g(z)={{a_{\rm p}}\over{1+4(z-z_{\rm p})^2/w^2_{\rm p}}},
 4391   $$
 4392   where $z_{\rm p}$ is the position, $a_{\rm p}$ is the zero-to-peak amplitude,
 4393   and $w_{\rm p}$ the full width half maximum of the perturbation.
 4394   This form of perturbation applied to chirped sinusoidal magneto-optical Bragg
 4395   gratings has in a linear optical regime been analyzed for spectral windowing
 4396   and filtering, in [F.~Jonsson and C.~Flytzanis, JOSAB (2005);
 4397   F.~Jonsson and C.~Flytzanis, Proc. MRS Fall meeting (2005)].
 4398   
 4399   
 4400   @<Add perturbation of gyration constant along grating structure@>={
 4401      for (j=1;j<=nn-1;j++) {
 4402         tmp=2.0*(z[j]-gyroperturb_position)/gyroperturb_width;
 4403         g[j]+=gyroperturb_amplitude/(1.0+tmp*tmp);
 4404      }
 4405   }
 4406   
 4407   @ Set the refractive index of the medium surrounding the magneto-optical
 4408   Bragg grating.
 4409   The first and last elements of the double vectors |n[0,nn]| and |g[0,nn]|
 4410   are defined according to the convention
 4411   $$
 4412     \eqalign{
 4413       |n[0]|&\equiv n(z^-_0),\qquad
 4414       |n[nn]|\equiv n(z^+_N),\cr
 4415       |g[0]|&\equiv g(z^-_0),\qquad
 4416       |g[nn]|\equiv g(z^+_N),\cr
 4417     }
 4418   $$
 4419   and the surrounding medium is here assumed to be linear,
 4420   $$
 4421     p_{\rm e,m}(z^-_0)=p_{\rm e,m}(z^+_N)
 4422       =q_{\rm e,m}(z^-_0)=q_{\rm e,m}(z^+_N)=0,
 4423   $$
 4424   and non-gyrotropic ($g_0=g_N=0$).
 4425   
 4426   @<Initiate surrounding medium@>=
 4427   {
 4428      n[0]=nsurr;  /* $n(z^-_0)$ */
 4429      n[nn]=nsurr; /* $n(z^+_N)$ */
 4430      g[0]=0.0;    /* $g(z^-_0)$ */
 4431      g[nn]=0.0;   /* $g(z^+_N)$ */
 4432   }
 4433   
 4434   @*Calculation of intra-grating layer reflectances.
 4435   Calculate the intrinsic reflectances over the layer interfaces prior to
 4436   entering the algorithm of calculation of field distributions or reflection and
 4437   transmission coefficients.
 4438   The reflectance and transmission coefficients across the layers are calculated
 4439   in terms of their linear optical and magneto-optical material parameters as
 4440   $$
 4441     \eqalign{
 4442       taup[j]&=\tau_+(z_j)
 4443         ={{2(n_{j-1}+g_{j-1})}\over{(n_{j-1}+n_j+g_{j-1}+g_j)}},\qquad
 4444       taum[j]=\tau_-(z_j)
 4445         ={{2(n_{j-1}-g_{j-1})}\over{(n_{j-1}+n_j-g_{j-1}-g_j)}},\cr
 4446       taupp[j]&=\tau'_+(z_j)
 4447         ={{2(n_j-g_j)}\over{(n_{j-1}+n_j-g_{j-1}-g_j)}},\qquad
 4448       taupm[j]=\tau'_-(z_j)
 4449         ={{2(n_j+g_j)}\over{(n_{j-1}+n_j+g_{j-1}+g_j)}},\cr
 4450       rhop[j]&=\rho_+(z_j)
 4451         ={{(n_{j-1}-n_j+g_{j-1}-g_j)}\over{(n_{j-1}+n_j+g_{j-1}+g_j)}},\qquad
 4452       rhom[j]=\rho_-(z_j)
 4453         ={{(n_{j-1}-n_j-g_{j-1}+g_j)}\over{(n_{j-1}+n_j-g_{j-1}-g_j)}},\cr
 4454       rhopp[j]&=\rho'_+(z_j)=-\rho_-(z_j),\hskip 60pt
 4455       rhopm[j]=\rho'_-(z_j)=-\rho_+(z_j),\cr
 4456     }
 4457   $$
 4458   for interface $z=z_j$, $j=1,2,\ldots,|nn|$, where $n_j$ and $g_j$ are the
 4459   respective refractive indices and gyration constants of the layers
 4460   $z_j<z<z_{j+1}$.
 4461   Outside the grating a zero gyration coefficient is assumed while the refractive
 4462   indices are specified by $n_0=n_N=|nsurr|$, as given through the command line
 4463   options.
 4464   
 4465   In these expressions, $\tau_{\pm}(z_j)$ are the layer reflectances for
 4466   forward propagating left/right circularly polarized light
 4467   (i.~e.~for light coming from the negative $z$-direction), while
 4468   $\tau'_{\pm}(z_j)$ are the layer reflectances for backward propagating
 4469   left/right circularly polarized light
 4470   (i.~e.~for light coming from the positive $z$-direction).
 4471   
 4472   These polarization selective amplitude reflectances satisfy the Stokes
 4473   relations
 4474   $$
 4475     \rho_{\pm}(z_j)=-\rho'_{\mp}(z_j),\qquad
 4476     \tau_{\pm}(z_j)\tau'_{\mp}(z_j)=1-\rho^2_{\pm}(z_j),
 4477   $$
 4478   in this particular case generalized to interfaces between magneto-optic media.
 4479   Notice the reversed order of the subscripts of the reflectances in the Stokes
 4480   relations, reflecting the nonreciprocity of the magneto-optical contributions
 4481   to the refractive index.
 4482   
 4483   @<Calculate intragrating layer reflectances@>=
 4484   {
 4485      for (j=1;j<=nn;j++) {
 4486         taup[j]=2.0*(n[j-1]+g[j-1])/(n[j-1]+n[j]+g[j-1]+g[j]);
 4487         taum[j]=2.0*(n[j-1]-g[j-1])/(n[j-1]+n[j]-g[j-1]-g[j]);
 4488         taupp[j]=2.0*(n[j]-g[j])/(n[j-1]+n[j]-g[j-1]-g[j]);
 4489         taupm[j]=2.0*(n[j]+g[j])/(n[j-1]+n[j]+g[j-1]+g[j]);
 4490         rhop[j]=(n[j-1]-n[j]+g[j-1]-g[j])/(n[j-1]+n[j]+g[j-1]+g[j]);
 4491         rhom[j]=(n[j-1]-n[j]-g[j-1]+g[j])/(n[j-1]+n[j]-g[j-1]-g[j]);
 4492         rhopp[j]=-rhom[j];
 4493         rhopm[j]=-rhop[j];
 4494      }
 4495   }
 4496   
 4497   @*Calculating the electrical field distribution inside the grating.
 4498   Having constructed all data needed for the analysis of optical wave
 4499   propagation in the grating structure, in linear as well as nonlinear,
 4500   all-optically as well as magneto-optically, we are now in position of
 4501   entering the actual electromagnetic field calculations.
 4502   The field calculation is performed for a set of vacuum wavelengths within
 4503   the spectral range specified by |lambdastart| and |lambdastop|.
 4504   The spectrum is sampled using equidistantly spaced wavelength increments.
 4505   
 4506   If the user instead of stating equidistantly spaced transmitted intensities
 4507   and ellipticities has specified a file where to find the trajectory of
 4508   Stokes parameters $(W_0,W_3)$ for the transmitted light, by using the
 4509   \.{--trmtraject} option, then |mme| is set to be equal to the number of
 4510   points |mmtraject| on this trajectory, and |mmi| set to one. For this case,
 4511   for every value of $|ke|=1,2,3,\ldots,|mme|$, the |trmintensity| and
 4512   |trmellipticity| variables will be set according to the data supplied
 4513   in the specified trajectory file.
 4514   
 4515   @<Calculate incident optical field spectrum@>=
 4516   {
 4517      for (k=1;k<=mm;k++) { /* for all wavelengths in the spectrum window */
 4518         if (mm>1) { /* if more than one sampling point in the spectrum */
 4519            lambda=lambdastart+(((double)(k-1))/((double)(mm-1)))
 4520               *(lambdastop-lambdastart);
 4521         } else {
 4522            lambda=lambdastart;
 4523         }
 4524         omega=twopi*c/lambda; /*angular frequency of the light */
 4525         if (trmtraject_specified) {
 4526            mme=mmtraject;
 4527            mmi=1;
 4528         }
 4529         @<Scan transmitted optical field in ellipticity and intensity@>;
 4530      }
 4531      if (verbose) @<Display elapsed execution time@>;
 4532   }
 4533   
 4534   @ Display the total execution time consumed by the simulation. This is the last
 4535   block to be executed by the program, and employs the |difftime| routine of the
 4536   standard \CEE\ library \.{time.h}.
 4537   
 4538   @<Display elapsed execution time@>=
 4539   {
 4540      fprintf(stdout," ...done.                     ");
 4541      now=time(NULL);
 4542      fprintf(stdout,"Elapsed execution time: %d s\n",
 4543         ((int)difftime(now,initime)));
 4544      for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
 4545      fprintf(stdout,"Program execution closed %s",ctime(&now));
 4546   }
 4547   
 4548   @ For a specified range of the intensity and ellipticity of polarization state
 4549   of the transmitted optical field, calculate the corresponding incident fields
 4550   in this inverse formulation of the electromagnetic wave propagation problem.
 4551   The range of the ellipticity $\varepsilon_{\rm T}$ of the polarization state
 4552   of the transmitted optical field is given as
 4553   $$\varepsilon_{\rm T}\in[|trmellipstart|,|trmellipstop|],$$
 4554   where |trmellipstart| and |trmellipstop| are the parameters provided at
 4555   startup of the program through the command line option
 4556   \.{--trmellipticity} $\langle|trmellipstart|\rangle$
 4557   $\langle|trmellipstop|\rangle$ $\langle|mme|\rangle$.
 4558   Via the definition of the normalized ellipticity $\varepsilon_{\rm T}$,
 4559   the |trmellipstart| and |trmellipstop| parameters are bound to
 4560   $$-1\le|trmellipstart|\le|trmellipstop|\le 1.$$
 4561   
 4562   @<Scan transmitted optical field in ellipticity and intensity@>=
 4563   {
 4564      for (ke=1;ke<=mme;ke++) {
 4565         if (trmtraject_specified) {
 4566            trmellipticity=w3traj[ke]/w0traj[ke];
 4567         } else {
 4568            if (mme>1) {
 4569               trmellipticity=trmellipstart+(((double)(ke-1))/((double)(mme-1)))
 4570                  *(trmellipstop-trmellipstart);
 4571            } else {
 4572               trmellipticity=trmellipstart;
 4573            }
 4574         }
 4575         @<Scan transmitted optical field in intensity@>;
 4576      }
 4577   }
 4578   
 4579   @ For a specified range of the intensity of the transmitted optical field,
 4580   calculate the corresponding incident fields in this inverse formulation of
 4581   the electromagnetic wave propagation problem.
 4582   The range of the intensity $I_{\rm T}$ of the transmitted optical field is
 4583   given as $$I_{\rm T}\in[|trmintenstart|,|trmintenstop|],$$
 4584   where |trmintenstart| and |trmintenstop| are the parameters provided at
 4585   startup of the program through the command line option
 4586   \.{--trmintensity} $\langle|trmintenstart|\rangle$
 4587   $\langle|trmintenstop|\rangle$ $\langle|mmi|\rangle$.
 4588   
 4589   @<Scan transmitted optical field in intensity@>=
 4590   {
 4591      for (ki=1;ki<=mmi;ki++) {
 4592         if (trmtraject_specified) {
 4593            trmintensity=(epsilon0*c/2.0)*w0traj[ke];
 4594         } else {
 4595            if (mmi>1) {
 4596               trmintensity=trmintenstart
 4597                     +(((double)(ki-1))/((double)(mmi-1)))
 4598                         *(trmintenstop-trmintenstart);
 4599            } else {
 4600               trmintensity=trmintenstart;
 4601            }
 4602         }
 4603         @<Set boundary conditions at end of grating@>;
 4604         @<Calculate optical field in last layer of the grating@>;
 4605         @<Propagate optical fields from last to first layer of the grating@>;
 4606         @<Write Stokes parameters and reflection coefficients to file@>;
 4607         @<Write intragrating field evolution to file@>;
 4608         @<Write intragrating intensity evolution to file@>;
 4609         @<Write spatial grating structure to file@>;
 4610      }
 4611   }
 4612   
 4613   @ In this inverse formulation of the algorithm, apply the boundary condition
 4614   that the backward propagating wave at the end of the grating is zero,
 4615   $$
 4616     E^{\rm b}_{N_{\pm}}(z_N)\equiv E^{\rm b}_{\pm}(z^+_N)=0,
 4617   $$
 4618   and that the forward propagating field is a given quantity, specified
 4619   in terms of intensity and ellipticity of the polarization state, as
 4620   $$
 4621     \eqalign{
 4622       E^{\rm f}_{N_+}(z_N)\equiv E^{\rm f}_+(z^+_N)
 4623       &=\left[(1+\varepsilon_{\rm T})I_{\rm T}/(\varepsilon_0 c)\right]^{1/2},\cr
 4624       E^{\rm f}_{N_-}(z_N)\equiv E^{\rm f}_-(z^+_N)
 4625       &=\left[(1-\varepsilon_{\rm T})I_{\rm T}/(\varepsilon_0 c)\right]^{1/2},\cr
 4626     }
 4627   $$
 4628   with values of transmitted intensity and ellipticity in the range specified
 4629   by parameters parsed from the command line options, supplied during startup
 4630   of the program.
 4631   Here the transmitted intensity $I_{\rm T}$ (in the program described by the
 4632   variable |trmintensity|) is expressed in regular \SI\ units,
 4633   in ${\rm W}/{\rm m}^2$ (Watts per square meter), as
 4634   $$
 4635     I_{\rm T}=(c\varepsilon_0/2)
 4636       (\vert E^{\rm f}_+(z^+_N)\vert^2+\vert E^{\rm f}_-(z^+_N)\vert^2),
 4637   $$
 4638   and the normalized transmitted ellipticity $\varepsilon_{\rm T}$ of the
 4639   transmitted polarization state (in the program described by the
 4640   variable |trmellipticity|)
 4641   $$
 4642     \varepsilon_{\rm T}
 4643       ={{\vert E^{\rm f}_+(z^+_N)\vert^2-\vert E^{\rm f}_-(z^+_N)\vert^2}
 4644         \over{\vert E^{\rm f}_+(z^+_N)\vert^2+\vert E^{\rm f}_-(z^+_N)\vert^2}},
 4645   $$
 4646   is a number in the range from $-1$ to $1$, with $-1$ corresponding to right
 4647   circularly polarized (RCP), $0$ to linearly polarized, and $1$ left circularly
 4648   polarized (LCP) light.
 4649   
 4650   @<Set boundary conditions at end of grating@>=
 4651   {
 4652      ebp[nn]=complex(0.0,0.0);
 4653      ebm[nn]=complex(0.0,0.0);
 4654      efp[nn]=complex(sqrt((1.0+trmellipticity)*trmintensity/(c*epsilon0)),0.0);
 4655      efm[nn]=complex(sqrt((1.0-trmellipticity)*trmintensity/(c*epsilon0)),0.0);
 4656   }
 4657   
 4658   @ Having applied the boundary conditions at the end of the grating, calculate
 4659   the optical fields in the last layer, for which $j=N-1$. These fields are
 4660   taken immediately next to the last interface, at $z=z^-_N$.
 4661   
 4662   @<Calculate optical field in last layer of the grating@>=
 4663   {
 4664     efp[nn-1]=cmul(crdiv(efp[nn],taup[nn]),crexpi(-omega*n[nn-1]*dz[nn-1]/c));
 4665     efm[nn-1]=cmul(crdiv(efm[nn],taum[nn]),crexpi(-omega*n[nn-1]*dz[nn-1]/c));
 4666     ebp[nn-1]=cmul(rcmul(rhom[nn],efm[nn-1]),
 4667       crexpi(2.0*omega*n[nn-1]*dz[nn-1]/c));
 4668     ebm[nn-1]=cmul(rcmul(rhop[nn],efp[nn-1]),
 4669       crexpi(2.0*omega*n[nn-1]*dz[nn-1]/c));
 4670   }
 4671   
 4672   @ Given the right and left circularly polarized components of the forward
 4673   and backward propagating optical fields in the last layer, iterate the
 4674   propagation over the whole grating structure in order to find the
 4675   corresponding input optical fields. This is done in an iterative manner
 4676   over all the layers $z_j$, starting with the last layer (for which $j=N-1$)
 4677   and ending up at the first layer (for which $j=1$), successively propagating
 4678   the optical field over one layer at the time.
 4679   
 4680   As we enter the loop in the order $j=N-1,N-2,...,1$, the forward and backward
 4681   propagating optical field components immediately to the ``left'' of $z_{j+1}$
 4682   are contained in the complex vector elements |efp[j]|, |efm[j]|, |ebp[j]|, and
 4683   |ebm[j]|, with
 4684   $$
 4685     \eqalign{
 4686       |efp[j]|&=E^f_{j_+}(z^-_{j+1}),\qquad
 4687       |efm[j]|=E^f_{j_-}(z^-_{j+1}),\qquad
 4688       |ebp[j]|=E^b_{j_+}(z^-_{j+1}),\qquad
 4689       |ebm[j]|=E^b_{j_-}(z^-_{j+1}),\cr
 4690     }
 4691   $$
 4692   where $z=z^-_j$ denotes the position immediately to the ``left''
 4693   of $z=z_j$. We will now propagate the fields from $z_{j+1}$ to $z_j$,
 4694   for $j=N-1,N-2,...,1$ (in that order), by first calculating the
 4695   nonlinear (optical field-dependent) propagation constants of the current
 4696   layer $z_j < z < z_{j+1}$.
 4697   
 4698   This block of code also deals with displaying information on the progress of
 4699   calculation, using the standard \ANSICEE\ time library for the calculation
 4700   of ``estimated time of arrival'' (ETA) for the finishing of execution.
 4701   
 4702   @<Propagate optical fields from last to first layer of the grating@>=
 4703   {
 4704      for (j=nn-1;j>=1;j--) {
 4705         @<Calculate nonlinear propagation constants of layer@>;
 4706         @<Propagate fields over homogeneous layer@>;
 4707         @<Propagate fields over interface to next layer@>;
 4708         if (verbose) {
 4709            @<Display simulation status and estimated time of arrival@>;
 4710         }
 4711      }
 4712   }
 4713   
 4714   @ Calculate the nonlinear, optical field- and polarization-dependent
 4715   contributions to the refractive index, including electric dipolar
 4716   (all-optical) as well as magetic dipolar (magneto-optical) contributions.
 4717   
 4718   Here the local variables are defined as
 4719   $$
 4720     \eqalign{
 4721       |aafp2|&=\vert E^f_{j_+}(z_j)\vert^2,
 4722         \qquad|etafp[j]|=\eta^{\rm f}_+(z_j)\cr
 4723       |aafm2|&=\vert E^f_{j_-}(z_j)\vert^2,
 4724         \qquad|etafm[j]|=\eta^{\rm f}_-(z_j)\cr
 4725       |aabp2|&=\vert E^b_{j_+}(z_j)\vert^2,
 4726         \qquad|etabp[j]|=\eta^{\rm b}_+(z_j)\cr
 4727       |aabm2|&=\vert E^b_{j_-}(z_j)\vert^2,
 4728         \qquad|etabm[j]|=\eta^{\rm b}_-(z_j)\cr
 4729     }
 4730   $$
 4731   and the optical field-dependent propagation constants $\eta^{\rm f}_{\pm}$
 4732   and $\eta^{\rm b}_{\pm}$ are given in terms of the optical fields and
 4733   material parameters of the layer $z_j<z<z_{j+1}$ as
 4734   $$
 4735     \eqalign{
 4736      etafp[j]&={{3}\over{8 n_j}}
 4737         ((pe[j]+pm[j])
 4738           (\vert E^f_{j_+}(z_j)\vert^2+2\vert E^b_{j_-}(z_j)\vert^2)
 4739        +(qe[j]+qm[j])
 4740           (\vert E^f_{j_-}(z_j)\vert^2+\vert E^b_{j_+}(z_j)\vert^2)),\cr
 4741      etafm[j]&={{3}\over{8 n_j}}
 4742         ((pe[j]-pm[j])
 4743           (\vert E^f_{j_-}(z_j)\vert^2+2\vert E^b_{j_+}(z_j)\vert^2)
 4744        +(qe[j]-qm[j])
 4745           (\vert E^f_{j_+}(z_j)\vert^2+\vert E^b_{j_-}(z_j)\vert^2)),\cr
 4746      etabp[j]&={{3}\over{8 n_j}}
 4747         ((pe[j]-pm[j])
 4748           (\vert E^b_{j_+}(z_j)\vert^2+2\vert E^f_{j_-}(z_j)\vert^2)
 4749        +(qe[j]-qm[j])
 4750           (\vert E^b_{j_-}(z_j)\vert^2+\vert E^f_{j_+}(z_j)\vert^2)),\cr
 4751      etabm[j]&={{3}\over{8 n_j}}
 4752         ((pe[j]+pm[j])
 4753           (\vert E^b_{j_-}(z_j)\vert^2+2\vert E^f_{j_+}(z_j)\vert^2)
 4754        +(qe[j]+qm[j])
 4755           (\vert E^b_{j_+}(z_j)\vert^2+\vert E^f_{j_-}(z_j)\vert^2)).\cr
 4756     }
 4757   $$
 4758   For a more strict derivation of these parameters, as governing the phase
 4759   evolution of light in homogeneous nonlinear magneto-optical Kerr-media,
 4760   see F.~Jonsson and C.~Flytzanis, {\it Phys.~Rev.~Lett.}~{\bf 82}, 1426 (1999).
 4761   
 4762   @<Calculate nonlinear propagation constants of layer@>=
 4763   {
 4764      aafp2=cdabs(efp[j]);
 4765      aafm2=cdabs(efm[j]);
 4766      aabp2=cdabs(ebp[j]);
 4767      aabm2=cdabs(ebm[j]);
 4768      aafp2*=aafp2; /* equals $\vert E^f_{j_+}(z_j)\vert^2$ */
 4769      aafm2*=aafm2; /* equals $\vert E^f_{j_-}(z_j)\vert^2$ */
 4770      aabp2*=aabp2; /* equals $\vert E^b_{j_+}(z_j)\vert^2$ */
 4771      aabm2*=aabm2; /* equals $\vert E^b_{j_-}(z_j)\vert^2$ */
 4772      tmp=3.0/(8.0*n[j]);
 4773      etafp[j]=tmp*((pe[j]+pm[j])*(aafp2+2.0*aabm2)
 4774                +(qe[j]+qm[j])*(aafm2+aabp2));
 4775      etafm[j]=tmp*((pe[j]-pm[j])*(aafm2+2.0*aabp2)
 4776                +(qe[j]-qm[j])*(aafp2+aabm2));
 4777      etabp[j]=tmp*((pe[j]-pm[j])*(aabp2+2.0*aafm2)
 4778                +(qe[j]-qm[j])*(aabm2+aafp2));
 4779      etabm[j]=tmp*((pe[j]+pm[j])*(aabm2+2.0*aafp2)
 4780                +(qe[j]+qm[j])*(aabp2+aafm2));
 4781   }
 4782   
 4783   @ Having calculated the nonlinear propagation constants of the layer, now
 4784   propagate the optical fields to the next interface in the negative
 4785   $z$-direction. This wave propagation in homogeneous slices of the medium
 4786   is performed using the analytical solution for loss-less propagation as
 4787   published in F.~Jonsson and C.~Flytzanis, Phys.~Rev.~Lett.~{\bf 82},
 4788   1426 (1999).
 4789   
 4790   After this propagation over the homogeneous slice (layer), the temporary
 4791   variables |tmpfp|, |tmpfm|, |tmpbp|, and |tmpbm| contain the forward and
 4792   backward travelling optical fields taken at the ``beginning'' of the current,
 4793   homogeneous segment.
 4794   
 4795   @<Propagate fields over homogeneous layer@>=
 4796   {
 4797      tmpfp=cmul(efp[j],crexpi(-omega*(etafp[j]+g[j])*dz[j]/c));
 4798      tmpfm=cmul(efm[j],crexpi(-omega*(etafm[j]-g[j])*dz[j]/c));
 4799      tmpbp=cmul(ebp[j],crexpi(omega*(etabp[j]-g[j])*dz[j]/c));
 4800      tmpbm=cmul(ebm[j],crexpi(omega*(etabm[j]+g[j])*dz[j]/c));
 4801   }
 4802   
 4803   @ Make the passage over the interface to the next layer. The infinitesimal
 4804   propagation of the waves over the interfaces between homogeneous layers is
 4805   performed by using the previously calculated reflection and transmission
 4806   coefficients, taking the linear magneto-optical effect into account as well.
 4807   
 4808   @<Propagate fields over interface to next layer@>=
 4809   {
 4810      if (j>1) {
 4811         efp[j-1]=crdiv(cmul(csub(tmpfp,rcmul(rhopm[j],tmpbm)),
 4812                           crexpi(-omega*n[j-1]*dz[j-1]/c)),taup[j]);
 4813         efm[j-1]=crdiv(cmul(csub(tmpfm,rcmul(rhopp[j],tmpbp)),
 4814                           crexpi(-omega*n[j-1]*dz[j-1]/c)),taum[j]);
 4815         ebp[j-1]=cadd(rcmul(taupp[j],
 4816                  cmul(tmpbp,crexpi(omega*n[j-1]*dz[j-1]/c))),
 4817                rcmul(rhom[j],
 4818                  cmul(efm[j-1],crexpi(2.0*omega*n[j-1]*dz[j-1]/c))));
 4819         ebm[j-1]=cadd(rcmul(taupm[j],
 4820                  cmul(tmpbm,crexpi(omega*n[j-1]*dz[j-1]/c))),
 4821                rcmul(rhop[j],
 4822                  cmul(efp[j-1],crexpi(2.0*omega*n[j-1]*dz[j-1]/c))));
 4823      } else {
 4824         efp[0]=crdiv(csub(tmpfp,rcmul(rhopm[1],tmpbm)),taup[1]);
 4825         efm[0]=crdiv(csub(tmpfm,rcmul(rhopp[1],tmpbp)),taum[1]);
 4826         ebp[0]=cadd(rcmul(taupp[1],tmpbp),rcmul(rhom[1],efm[0]));
 4827         ebm[0]=cadd(rcmul(taupm[1],tmpbm),rcmul(rhop[1],efp[0]));
 4828      }
 4829   }
 4830   
 4831   @ Display the real-time progress in the simulation and calculate the estimated
 4832   time of arrival for finishing of the simulation. The completeness of the
 4833   simulation is displayed for every ten percent up to successful termination of
 4834   the program at one hundred percent.
 4835   
 4836   The formula for calculation of the progress is
 4837   $$
 4838     \Big\{\matrix{{\rm progress\ in}\cr{\rm percent}\cr}\Big\}=
 4839     100\times{{(N-j-1)+(k_{\rm i}-1)(N-1)+k_{\rm e}M_{\rm i}(N-1)+(k-1)M_{\rm e}
 4840       M_{\rm i}(N-1)}\over{M M_{\rm e} M_{\rm e}(N-1)}},
 4841   $$
 4842   where
 4843   $$
 4844     \eqalign{
 4845       1\le j\le N&\qquad{\rm [Layer\ counter\ index]}\cr
 4846       1\le k\le M&\qquad{\rm [Wavelength\ counter\ index]}\cr
 4847       1\le k_{\rm i}\le M_{\rm i}&\qquad{\rm [Intensity\ counter\ index]}\cr
 4848       1\le k_{\rm e}\le M_{\rm e}&\qquad{\rm [Ellipticity\ counter\ index]}\cr
 4849     }
 4850   $$
 4851   
 4852   @<Display simulation status and estimated time of arrival@>=
 4853   {
 4854      modf(100.0*((float)((nn-j-1)+(ki-1)*(nn-1)
 4855         +(ke-1)*mmi*(nn-1)+(k-1)*mme*mmi*(nn-1)))
 4856            /((float)(mm*mme*mmi*(nn-1))),&stn);
 4857      if (stn>status+10) {
 4858         status=status+10;
 4859         now=time(NULL);
 4860         eta=initime
 4861            +((int)((100.0/((double)status))*difftime(now,initime)));
 4862         fprintf(stdout," ...%2d percent finished...   ",status);
 4863         fprintf(stdout," ETA: %s",ctime(&eta));
 4864      }
 4865   }
 4866   
 4867   @ Having calculated the input electromagnetic field from the given output
 4868   field (as in this case, using the implicit way of calculating the
 4869   transmission characteristics of a nonlinear magneto-optical Bragg grating),
 4870   now calculate the corresponding incident $(S_0,S_1,S_2,S_3)$, transmitted
 4871   $(W_0,W_1,W_2,W_3)$, and reflected $(V_0,V_1,V_2,V_3)$ Stokes parameters
 4872   of the optical fields.
 4873   Notice that in this inverse formulation of the algorithm, the transmitted
 4874   Stokes parameters are not really calculated in a strict sense, since they
 4875   follow directly from the given input to the program -- the transmitted
 4876   optical field.
 4877   
 4878   The Stokes parameters are defined as conforming to the standard definition in
 4879   J.~D.~Jackson's {\it Classical Electrodynamics} (Wiley, New York, 1975), as
 4880   $$
 4881     \eqalign{
 4882       S_0&=\vert{E^f_+(z^-_0)}\vert^2+\vert{E^f_-(z^-_0)}\vert^2,\qquad\qquad
 4883       S_1=2\re[E^{f*}_+(z^-_0)E^f_-(z^-_0)],\cr
 4884       S_3&=\vert{E^f_+(z^-_0)}\vert^2-\vert{E^f_-(z^-_0)}\vert^2,\qquad\qquad
 4885       S_2=2\im[E^{f*}_+(z^-_0)E^f_-(z^-_0)],\cr
 4886     }
 4887   $$
 4888   for the incident wave,
 4889   $$
 4890     \eqalign{
 4891       W_0&=\vert{E^f_+(z^+_N)}\vert^2+\vert{E^f_-(z^+_N)}\vert^2,\qquad\qquad
 4892       W_1=2\re[E^{f*}_+(z^+_N)E^f_-(z^+_N)],\cr
 4893       W_3&=\vert{E^f_+(z^+_N)}\vert^2-\vert{E^f_-(z^+_N)}\vert^2,\qquad\qquad
 4894       W_2=2\im[E^{f*}_+(z^+_N)E^f_-(z^+_N)],\cr
 4895     }
 4896   $$
 4897   for the transmitted wave, and finally
 4898   $$
 4899     \eqalign{
 4900       V_0&=\vert{E^b_+(z^-_0)}\vert^2+\vert{E^b_-(z^-_0)}\vert^2,\qquad\qquad
 4901       V_1=2\re[E^{b*}_+(z^-_0)E^b_-(z^-_0)],\cr
 4902       V_3&=\vert{E^b_+(z^-_0)}\vert^2-\vert{E^b_-(z^-_0)}\vert^2,\qquad\qquad
 4903       V_2=2\im[E^{b*}_+(z^-_0)E^b_-(z^-_0)],\cr
 4904     }
 4905   $$
 4906   for the reflected wave of the grating structure. These parameters fully
 4907   specify the reflection and transmission characteristics for the nonlinear
 4908   magneto-optical grating structure, in a linear as well as nonlinear optical
 4909   domain. In particular, the intensity transmission and reflection coefficients
 4910   are expressed in as $T=W_0/S_0$ and $R=V_0/S_0$, respectively.
 4911   
 4912   In this calculation, a check is being performed regarding if the simulation
 4913   is being performed for a multiple set of intensities and ellipticities of the
 4914   transmitted light; if found to be so, then the set of Stokes parameters
 4915   are calculated in order to create topological graphs as in F.~Jonsson and
 4916   C.~Flytzanis, {\it Phys.~Rev.~Lett.}~{\bf 82}, 1426 (1999), in which case only
 4917   one particular wavelength should being considered for the simulation
 4918   (otherwise we would end up with too many topological graphs to keep track of);
 4919   otherwise the complex-valued amplitude reflection and transmission
 4920   coefficients,
 4921   $$
 4922     \rho_{\pm}(\omega)=E^{\rm b}_{0_{\mp}}(z_0)/E^{\rm f}_{0_{\pm}}(z_0),
 4923     \qquad\tau_{\pm}(\omega)=E^{\rm f}_{N_{\pm}}(z_N)/E^{\rm f}_{0_{\pm}}(z_0),
 4924   $$
 4925   are calculated, in order to create graphs of the spectral reflection and
 4926   transmission properties of the magneto-optical grating for circularly
 4927   polarized fields (in which case $k>1$ is implicitly assumed).
 4928   
 4929   If Stokes parameters are generated as data ouput,
 4930   the resulting output files (named according to the suffix convention
 4931   |outfilename|{\tt.s0.dat}, |outfilename|{\tt.s1.dat}, $\ldots$
 4932   |outfilename|{\tt.v0.dat}, $\ldots$, etc.),
 4933   can after the simulation be used for creating topological graphs.
 4934   
 4935   For instance, by mapping the contents of Stokes parameter files
 4936   |outfilename|{\tt.s0.dat}, |outfilename|{\tt.s3.dat},
 4937   and |outfilename|{\tt.w0.dat}
 4938   (using, for example, the \MATLAB\ command \.{mesh(s0,s3./s0,w0)},
 4939   assuming that the variables \.{s0}, \.{s3}, and \.{w0} were loaded
 4940   using the \MATLAB\ commands
 4941   \.{s0=load(|outfilename|.s0.dat);} \.{s3=load(|outfilename|.s3.dat);}
 4942   \.{w0=load(|outfilename|.w0.dat);}),
 4943   one gets a topological graph showing (|s0|,|s3|,|w0|) as defining a surface
 4944   showing the transmitted intensity |w0| as function of the input intensity
 4945   |s0| and input ellipticity |s3|.
 4946   
 4947   Similarly, two-dimensional graphs can be generated by, as an example,
 4948   instead using the \MATLAB\ command \.{contour(s3./s0,w3./w0,s0)},
 4949   to get graphs of the transmitted ellipticity \.{w3./w0} ($|w3|/|w0|$,
 4950   the ``$y$-coordinate'') as function of the input ellipticity \.{s3./s0}
 4951   ($|s3|/|s0|$, the ``$x$-coordinate''), for various values of the input
 4952   intensity \.{s0} ($|s0|$, the ``$z$-coordinate'').
 4953   This way of creating two-dimensional graphs from a parametric hypersurface
 4954   of Stokes-parameters might seem to be a cumbersome
 4955   way of generating a visible output; however, it actually turns out to be
 4956   a very convenient method. Once one has adopted to this somewhat topologically
 4957   directed way of thinking, any element of the Stokes vector is easily
 4958   visualized as function of any of the other variables, and one avoids the
 4959   difficulty that arise whenever the parameter of interest is a multivalued
 4960   function of the other parameters (particularly appreciated when considering,
 4961   for example, optically bistable behaviour of the structure, since one for
 4962   those cases carefully must sort out data that belong to different state
 4963   branches).
 4964   
 4965   As a default, and as a matter of convention of electrodynamics, all Stokes
 4966   parameters are given in ${\rm V}^2/{\rm m}^2$, through their definition.
 4967   For example, the incident field (which is calculated by the program in
 4968   this inverse formulation of the problem) is expressed in terms of the Stokes
 4969   parameters as
 4970   $$
 4971   \eqalign{
 4972     S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
 4973     S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
 4974     S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
 4975     S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
 4976   }
 4977   $$
 4978   However, the direct interpretation of these quantities in terms of squared
 4979   Volts per square metres is sometimes somewhat inconvenient; therefore, those
 4980   parameters can be scaled to give an interpretation of the intensity (in regular
 4981   \SI\ units measured in Watts per square metres),
 4982   as $S'_k=(\varepsilon_0 c/2)S_k$, or explicitly
 4983   $$
 4984   \eqalign{
 4985     S'_0&=(\varepsilon_0 c/2)
 4986        [\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2],\qquad
 4987     S'_1=(\varepsilon_0 c/2)
 4988        2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
 4989     S'_3&=(\varepsilon_0 c/2)
 4990        [\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2],\qquad
 4991     S'_2=(\varepsilon_0 c/2)
 4992        2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
 4993   }
 4994   $$
 4995   In this representation, $S'_0$ is now identical to the incident intensity
 4996   $I_{\rm in}$ [${\rm W}/{\rm m}^2$].
 4997   In order to have those scaled Stokes parameters $S'_k$ written to file,
 4998   rather than the default ones, one convenient possibility is to use the
 4999   previously added \.{--scale\_stokesparams} option, to include
 5000   \.{--scale\_stokesparams 1.327209e-3} at the command line when invoking
 5001   the program.
 5002   The numerical value of this scaling was obtained from\footnote{$\dagger$}{In
 5003   regular \SI\ units, the physical dimension of the quantity $\varepsilon_0 c/2$
 5004   is $[{\rm F}/{\rm s}]=[{\rm C}/({\rm V}\cdot{\rm s})]$,
 5005   so the physical dimension of $(\varepsilon_0 c/2)S_k$ is easily verified as
 5006   $[{\rm C}/({\rm V}\cdot{\rm s})][{\rm V}^2/{\rm m}^2]
 5007      =[{\rm C}\cdot{\rm V}/({\rm m}^2\cdot{\rm s})]
 5008      =[{\rm J}/({\rm m}^2\cdot{\rm s})]
 5009      =[{\rm W}/{\rm m}^2]$, as expected for a physical quantity describing an
 5010   energy flow per unit area.
 5011   }
 5012   $$
 5013     \eqalign{
 5014       \varepsilon_0 c/2
 5015         &=(8.854187817\ldots\times 10^{-12}\ {\rm F}/{\rm m})
 5016           \times(2.99792458\times 10^8\ {\rm m}/{\rm s})/2\cr
 5017         &\approx 1.327209\times 10^{-3}\ {\rm F}/{\rm s}.\cr
 5018     }
 5019   $$
 5020   
 5021   @<Write Stokes parameters and reflection coefficients to file@>=
 5022   {
 5023      /* Scan the grating spatially for the maximum intra-grating intensity. */
 5024      /* This is performed with the original, unscaled Stokes parameters. */
 5025      if (intensityinfo) {
 5026         for (j=0;j<=nn;j++) {
 5027            tmp=(epsilon0*n[j]*c/2)*(cabs2(efp[j])+cabs2(efm[j]));
 5028            if (maxintens < tmp) {
 5029               maxintens=tmp;
 5030               maxintens_layer=j;
 5031               maxintens_inintens=(epsilon0*nsurr*c/2)
 5032                  *(cabs2(efp[0])+cabs2(efm[0]));
 5033               maxintens_inellip=(cabs2(efp[0])-cabs2(efm[0]))
 5034                  /(cabs2(efp[0])+cabs2(efm[0]));
 5035               maxintens_trintens=(epsilon0*nsurr*c/2)
 5036                  *(cabs2(efp[nn])+cabs2(efm[nn]));
 5037               maxintens_trellip=(cabs2(efp[nn])-cabs2(efm[nn]))
 5038                  /(cabs2(efp[nn])+cabs2(efm[nn]));
 5039            }
 5040         }
 5041      }
 5042      if ((mme>1)&&(mmi>1)) { /* ``topological'' mode */
 5043         /* Stokes parameters of input optical wave */
 5044         s0=cabs2(efp[0])+cabs2(efm[0]);
 5045         s1=2.0*cmul(conjg(efp[0]),efm[0]).r;
 5046         s2=2.0*cmul(conjg(efp[0]),efm[0]).i;
 5047         s3=cabs2(efp[0])-cabs2(efm[0]);
 5048         if (scale_stokesparams) {
 5049            s0=s0*stoke_scalefactor;
 5050            s1=s1*stoke_scalefactor;
 5051            s2=s2*stoke_scalefactor;
 5052            s3=s3*stoke_scalefactor;
 5053         }
 5054         if (normalize_ellipticity) s3=s3/s0;
 5055         fprintf(fp_s0,"%16.12e  ",s0);
 5056         fprintf(fp_s1,"%16.12e  ",s1);
 5057         fprintf(fp_s2,"%16.12e  ",s2);
 5058         fprintf(fp_s3,"%16.12e  ",s3);
 5059         fflush(fp_s0);
 5060         fflush(fp_s1);
 5061         fflush(fp_s2);
 5062         fflush(fp_s3);
 5063   
 5064         /* Stokes parameters of reflected optical wave */
 5065         v0=cabs2(ebp[0])+cabs2(ebm[0]);
 5066         v1=2.0*cmul(conjg(ebp[0]),ebm[0]).r;
 5067         v2=2.0*cmul(conjg(ebp[0]),ebm[0]).i;
 5068         v3=cabs2(ebp[0])-cabs2(ebm[0]);
 5069         if (scale_stokesparams) {
 5070            v0=v0*stoke_scalefactor;
 5071            v1=v1*stoke_scalefactor;
 5072            v2=v2*stoke_scalefactor;
 5073            v3=v3*stoke_scalefactor;
 5074         }
 5075         if (normalize_ellipticity) v3=v3/v0;
 5076         fprintf(fp_v0,"%16.12e  ",v0);
 5077         fprintf(fp_v1,"%16.12e  ",v1);
 5078         fprintf(fp_v2,"%16.12e  ",v2);
 5079         fprintf(fp_v3,"%16.12e  ",v3);
 5080         fflush(fp_v0);
 5081         fflush(fp_v1);
 5082         fflush(fp_v2);
 5083         fflush(fp_v3);
 5084   
 5085         /* Stokes parameters of transmitted optical wave */
 5086         w0=cabs2(efp[nn])+cabs2(efm[nn]);
 5087         w1=2.0*cmul(conjg(efp[nn]),efm[nn]).r;
 5088         w2=2.0*cmul(conjg(efp[nn]),efm[nn]).i;
 5089         w3=cabs2(efp[nn])-cabs2(efm[nn]);
 5090         if (scale_stokesparams) {
 5091            w0=w0*stoke_scalefactor;
 5092            w1=w1*stoke_scalefactor;
 5093            w2=w2*stoke_scalefactor;
 5094            w3=w3*stoke_scalefactor;
 5095         }
 5096         if (normalize_ellipticity) w3=w3/w0;
 5097         fprintf(fp_w0,"%16.12e  ",w0);
 5098         fprintf(fp_w1,"%16.12e  ",w1);
 5099         fprintf(fp_w2,"%16.12e  ",w2);
 5100         fprintf(fp_w3,"%16.12e  ",w3);
 5101         fflush(fp_w0);
 5102         fflush(fp_w1);
 5103         fflush(fp_w2);
 5104         fflush(fp_w3);
 5105      } else { /* ``spectrum'' mode */
 5106         if (stokes_parameter_spectrum) { /* spectrum of Stokes parameters */
 5107            /* Stokes parameters of input optical wave */
 5108            s0=cabs2(efp[0])+cabs2(efm[0]);
 5109            s1=2.0*cmul(conjg(efp[0]),efm[0]).r;
 5110            s2=2.0*cmul(conjg(efp[0]),efm[0]).i;
 5111            s3=cabs2(efp[0])-cabs2(efm[0]);
 5112            fprintf(fp_spec,"%16.12e %16.12e %16.12e %16.12e %16.12e\n",
 5113                       lambda,omega,s1/s0,s2/s0,s3/s0);
 5114            fflush(fp_spec);
 5115   
 5116            /* Stokes parameters of reflected optical wave */
 5117            v0=cabs2(ebp[0])+cabs2(ebm[0]);
 5118            v1=2.0*cmul(conjg(ebp[0]),ebm[0]).r;
 5119            v2=2.0*cmul(conjg(ebp[0]),ebm[0]).i;
 5120            v3=cabs2(ebp[0])-cabs2(ebm[0]);
 5121            /* CODE FOR WRITING TO BE INSERTED HERE */
 5122   
 5123            /* Stokes parameters of transmitted optical wave */
 5124            w0=cabs2(efp[nn])+cabs2(efm[nn]);
 5125            w1=2.0*cmul(conjg(efp[nn]),efm[nn]).r;
 5126            w2=2.0*cmul(conjg(efp[nn]),efm[nn]).i;
 5127            w3=cabs2(efp[nn])-cabs2(efm[nn]);
 5128            /* CODE FOR WRITING TO BE INSERTED HERE */
 5129         }
 5130         if (save_dbspectra) { /* spectrum in dB */
 5131            tmp=(cabs2(ebp[0])+cabs2(ebm[0]))/(cabs2(efp[0])+cabs2(efm[0]));
 5132            fprintf(fp_irspec,"%-10.8f %-10.8f\n",lambda*1.0e9,10.0*log10(tmp));
 5133            fprintf(fp_itspec,"%-10.8f %-10.8f\n",lambda*1.0e9,10.0*log10(1.0-tmp));
 5134            fflush(fp_irspec);
 5135            fflush(fp_itspec);
 5136         } else { /* linear scale between zero and unity */
 5137            fprintf(fp_irspec,"%-10.8f %-10.8f\n",lambda*1.0e9,
 5138               (cabs2(ebp[0])+cabs2(ebm[0]))/(cabs2(efp[0])+cabs2(efm[0])));
 5139            fprintf(fp_itspec,"%-10.8f %-10.8f\n",lambda*1.0e9,
 5140               (cabs2(efp[nn])+cabs2(efm[nn]))/(cabs2(efp[0])+cabs2(efm[0])));
 5141            fflush(fp_irspec);
 5142            fflush(fp_itspec);
 5143         }
 5144         fprintf(fp_icspec,"%-10.8f %-10.8f\n",lambda*1.0e9,
 5145            (cabs2(ebp[0])+cabs2(ebm[0]))/(cabs2(efp[0])+cabs2(efm[0]))
 5146              +(cabs2(efp[nn])+cabs2(efm[nn]))/(cabs2(efp[0])+cabs2(efm[0])));
 5147         fflush(fp_icspec);
 5148      }
 5149   
 5150      if(ki>=mmi) {   /* Write linefeed at and of each scan of intensity */
 5151         if ((mme>1)&&(mmi>1)) {
 5152            fprintf(fp_s0,"\n");
 5153            fprintf(fp_s1,"\n");
 5154            fprintf(fp_s2,"\n");
 5155            fprintf(fp_s3,"\n");
 5156            fprintf(fp_v0,"\n");
 5157            fprintf(fp_v1,"\n");
 5158            fprintf(fp_v2,"\n");
 5159            fprintf(fp_v3,"\n");
 5160            fprintf(fp_w0,"\n");
 5161            fprintf(fp_w1,"\n");
 5162            fprintf(fp_w2,"\n");
 5163            fprintf(fp_w3,"\n");
 5164         }
 5165      }
 5166   }
 5167   
 5168   @ Check if the user has specified a filename for saving the electromagnetic
 5169   field as it propagates through the grating structure, with |nne| being the
 5170   number of discrete sampling points within each homogeneous layer.
 5171   (This is quite useful since we otherwise just would get samples of the
 5172   intra grating electromagnetic field at the boundaries of the homogeneous
 5173   layers of the model; for twolevel grating types with comparatively thick
 5174   layers this would otherwise, for example, cause unwanted discrete jumps
 5175   in the plots of the polarization state evolution in the grating structure.)
 5176   If so, write the full information of the electromagnetic field to file, to
 5177   be used for later graphs (not necessarily just in terms of Stokes parameters).
 5178   
 5179   @<Write intragrating field evolution to file@>=
 5180   {
 5181      if (fieldevoflag) {
 5182         if (fieldevoflag_efield) {
 5183            if (verbose)
 5184               fprintf(stdout,
 5185                  "Writing spatial field evolution to file.\n");
 5186            if (fp_evo!=NULL) {
 5187               for (j=1;j<=nn-1;j++) {
 5188                  for (jje=1;jje<=nne;jje++) {
 5189                     if (nne>1) {
 5190                        zt=z[j]+((double)(jje-1))*dz[j]/((double)(nne));
 5191                     } else {
 5192                        zt=z[j];
 5193                     }
 5194                     tmpfp=cmul(efp[j],
 5195                            crexpi(omega*(etafp[j]+g[j])*(zt-z[j])/c));
 5196                     tmpfm=cmul(efm[j],
 5197                            crexpi(omega*(etafm[j]-g[j])*(zt-z[j])/c));
 5198                         tmpbp=cmul(ebp[j],
 5199                            crexpi(-omega*(etabp[j]-g[j])*(zt-z[j])/c));
 5200                     tmpbm=cmul(ebm[j],
 5201                            crexpi(-omega*(etabm[j]+g[j])*(zt-z[j])/c));
 5202                     if (normalize_length_to_micrometer) {
 5203                        fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e"
 5204                                       " %16.12e %16.12e %16.12e %16.12e"
 5205                                       " %16.12e\n",zt*1.0e6,
 5206                                       tmpfp.r,tmpfp.i,tmpfm.r,tmpfm.i,
 5207                                       tmpbp.r,tmpbp.i,tmpbm.r,tmpbm.i);
 5208                     } else {
 5209                        fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e"
 5210                                       " %16.12e %16.12e %16.12e %16.12e"
 5211                                       " %16.12e\n",zt,
 5212                                       tmpfp.r,tmpfp.i,tmpfm.r,tmpfm.i,
 5213                                       tmpbp.r,tmpbp.i,tmpbm.r,tmpbm.i);
 5214                     }
 5215                  }
 5216               }
 5217               if (normalize_length_to_micrometer) {
 5218                  fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e %16.12e"
 5219                                 " %16.12e %16.12e %16.12e %16.12e\n",
 5220                              z[nn]*1.0e6,efp[nn].r,efp[nn].i,efm[nn].r,efm[nn].i,
 5221                                 ebp[nn].r,ebp[nn].i,ebm[nn].r,ebm[nn].i);
 5222               } else {
 5223                  fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e %16.12e"
 5224                                 " %16.12e %16.12e %16.12e %16.12e\n",
 5225                              z[nn],efp[nn].r,efp[nn].i,efm[nn].r,efm[nn].i,
 5226                                 ebp[nn].r,ebp[nn].i,ebm[nn].r,ebm[nn].i);
 5227               }
 5228            } else {
 5229               fprintf(stderr,"%s: Could not write to file %s!\n",
 5230                  progname,fieldevofilename);
 5231               exit(FAILURE);
 5232            }
 5233         } else if (fieldevoflag_stoke) {
 5234            if (verbose)
 5235               fprintf(stdout,
 5236                  "Writing spatial evolution of Stokes parameters to file.\n");
 5237            if ((fp_evo_s0!=NULL)&&(fp_evo_s1!=NULL)
 5238                  &&(fp_evo_s2!=NULL)&&(fp_evo_s3!=NULL)) {
 5239               for (j=1;j<=nn-1;j++) {
 5240                  for (jje=1;jje<=nne;jje++) {
 5241                     if (nne>1) {
 5242                        zt=z[j]+((double)(jje-1))*dz[j]/((double)(nne));
 5243                     } else {
 5244                        zt=z[j];
 5245                     }
 5246                     tmpfp=cmul(efp[j],
 5247                            crexpi(omega*(etafp[j]+g[j])*(zt-z[j])/c));
 5248                     tmpfm=cmul(efm[j],
 5249                            crexpi(omega*(etafm[j]-g[j])*(zt-z[j])/c));
 5250                         tmpbp=cmul(ebp[j],
 5251                            crexpi(-omega*(etabp[j]-g[j])*(zt-z[j])/c));
 5252                     tmpbm=cmul(ebm[j],
 5253                            crexpi(-omega*(etabm[j]+g[j])*(zt-z[j])/c));
 5254                     s0=cabs2(tmpfp)+cabs2(tmpfm);
 5255                     s1=2.0*cmul(conjg(tmpfp),tmpfm).r;
 5256                     s2=2.0*cmul(conjg(tmpfp),tmpfm).i;
 5257                     s3=cabs2(tmpfp)-cabs2(tmpfm);
 5258                     if (normalize_intensity) s0=s0/(cabs2(efp[1])+cabs2(efm[1]));
 5259                     if (normalize_length_to_micrometer) {
 5260                        fprintf(fp_evo_s0,"%16.12e %16.12e\n",zt*1.0e6,s0);
 5261                        fprintf(fp_evo_s1,"%16.12e %16.12e\n",zt*1.0e6,s1);
 5262                        fprintf(fp_evo_s2,"%16.12e %16.12e\n",zt*1.0e6,s2);
 5263                        fprintf(fp_evo_s3,"%16.12e %16.12e\n",zt*1.0e6,s3);
 5264                     } else {
 5265                        fprintf(fp_evo_s0,"%16.12e %16.12e\n",zt,s0);
 5266                        fprintf(fp_evo_s1,"%16.12e %16.12e\n",zt,s1);
 5267                        fprintf(fp_evo_s2,"%16.12e %16.12e\n",zt,s2);
 5268                        fprintf(fp_evo_s3,"%16.12e %16.12e\n",zt,s3);
 5269                     }
 5270                  }
 5271               }
 5272               s0=cabs2(efp[nn])+cabs2(efm[nn]);
 5273               s1=2.0*cmul(conjg(efp[nn]),efm[nn]).r;
 5274               s2=2.0*cmul(conjg(efp[nn]),efm[nn]).i;
 5275               s3=cabs2(efp[nn])-cabs2(efm[nn]);
 5276               if (normalize_intensity) s0=s0/(cabs2(efp[1])+cabs2(efm[1]));
 5277               if (normalize_length_to_micrometer) {
 5278                  fprintf(fp_evo_s0,"%16.12e %16.12e\n",z[nn]*1.0e6,s0);
 5279                  fprintf(fp_evo_s1,"%16.12e %16.12e\n",z[nn]*1.0e6,s1);
 5280                  fprintf(fp_evo_s2,"%16.12e %16.12e\n",z[nn]*1.0e6,s2);
 5281                  fprintf(fp_evo_s3,"%16.12e %16.12e\n",z[nn]*1.0e6,s3);
 5282               } else {
 5283                  fprintf(fp_evo_s0,"%16.12e %16.12e\n",z[nn],s0);
 5284                  fprintf(fp_evo_s1,"%16.12e %16.12e\n",z[nn],s1);
 5285                  fprintf(fp_evo_s2,"%16.12e %16.12e\n",z[nn],s2);
 5286                  fprintf(fp_evo_s3,"%16.12e %16.12e\n",z[nn],s3);
 5287               }
 5288            } else {
 5289               fprintf(stderr,"%s: Could not write to file %s, %s, %s, or %s!\n",
 5290                  progname,fieldevofilename_s0,fieldevofilename_s1,
 5291                           fieldevofilename_s2,fieldevofilename_s3);
 5292               exit(FAILURE);
 5293            }
 5294         } else {
 5295            fprintf(stderr,"%s: Unknown field evolution flag.\n"
 5296                           "%s: (This cannot happen)\n",progname,progname);
 5297            exit(FAILURE);
 5298         }
 5299      }
 5300   }
 5301   
 5302   @ Check if the user has specified a filename for saving the electromagnetic
 5303   intensity distribution inside the grating structure, with |nne| being the
 5304   number of discrete sampling points within each homogeneous layer.
 5305   
 5306   @<Write intragrating intensity evolution to file@>=
 5307   {
 5308      if (intensityevoflag) {
 5309         if (fabs(ievolambda-lambda)
 5310              <fabs(lambdastop-lambdastart)/((double)(mm))) {
 5311            if (verbose)
 5312               fprintf(stdout,"%s: Saving intensity evolution at lambda=%8.4e\n",
 5313                  progname,lambda);
 5314            if(strcmp(intensityevofilename,"")) {
 5315               if (fp_ievo!=NULL) {
 5316                  for (j=1;j<=nn-1;j++) {
 5317                     if (normalize_length_to_micrometer) {
 5318                        fprintf(fp_ievo,"%16.12e %16.12e\n",z[j]*1.0e6,
 5319                         (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
 5320                      /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
 5321                        fprintf(fp_ievo,"%16.12e %16.12e\n",z[j+1]*1.0e6,
 5322                        (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
 5323                      /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
 5324                     } else {
 5325                        fprintf(fp_ievo,"%16.12e %16.12e\n",z[j],
 5326                        (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
 5327                      /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
 5328                        fprintf(fp_ievo,"%16.12e %16.12e\n",z[j+1],
 5329                         (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
 5330                      /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
 5331                     }
 5332                  }
 5333               } else {
 5334                  fprintf(stderr,"%s: Could not write to file %s!\n",
 5335                     progname,intensityevofilename);
 5336                  exit(FAILURE);
 5337               }
 5338            }
 5339         }
 5340      }
 5341   }
 5342   
 5343   @ Check if the user has specified a filename for saving the spatial grating
 5344   structure to. If so, save the whole grating structure to disk; this is
 5345   useful as reference in graphs of the intragrating intensity and polarization
 5346   state evolution.
 5347   
 5348   @<Write spatial grating structure to file@>=
 5349   {
 5350      if (writegratingtofile) {
 5351         if ((fp_gr=fopen(gratingfilename,"w"))==NULL) {
 5352            fprintf(stderr,"%s: Could not open file %s for output!\n",
 5353               progname,gratingfilename);
 5354            exit(FAILURE);
 5355         }
 5356         if (normalize_length_to_micrometer) { /* length $z$ in micrometer */
 5357            if (display_surrounding_media) {
 5358               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5359                       " %16.12e %16.12e %16.12e\n",
 5360                       (z[1]-0.1*(z[nn]-z[1]))*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
 5361               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5362                       " %16.12e %16.12e %16.12e\n",
 5363                       z[1]*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
 5364            }
 5365            for (j=1;j<=nn-1;j++) {
 5366               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5367                          " %16.12e %16.12e %16.12e\n",
 5368                          z[j]*1.0e6,n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
 5369               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5370                          " %16.12e %16.12e %16.12e\n",
 5371                          z[j+1]*1.0e6,n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
 5372            }
 5373            if (display_surrounding_media) {
 5374               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5375                       " %16.12e %16.12e %16.12e\n",
 5376                       z[nn]*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
 5377               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5378                       " %16.12e %16.12e %16.12e\n",
 5379                       (z[nn]+0.1*(z[nn]-z[1]))*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
 5380            }
 5381         } else { /* length $z$ in meter */
 5382            if (display_surrounding_media) {
 5383               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5384                       " %16.12e %16.12e %16.12e\n",
 5385                       z[1]-0.1*(z[nn]-z[1]),nsurr,0.0,0.0,0.0,0.0,0.0);
 5386               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5387                       " %16.12e %16.12e %16.12e\n",
 5388                       z[1],nsurr,0.0,0.0,0.0,0.0,0.0);
 5389            }
 5390            for (j=1;j<=nn-1;j++) {
 5391               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5392                          " %16.12e %16.12e %16.12e\n",
 5393                          z[j],n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
 5394               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5395                          " %16.12e %16.12e %16.12e\n",
 5396                          z[j+1],n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
 5397            }
 5398            if (display_surrounding_media) {
 5399               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5400                       " %16.12e %16.12e %16.12e\n",
 5401                       z[nn],nsurr,0.0,0.0,0.0,0.0,0.0);
 5402               fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
 5403                       " %16.12e %16.12e %16.12e\n",
 5404                       z[nn]+0.1*(z[nn]-z[1]),nsurr,0.0,0.0,0.0,0.0,0.0);
 5405            }
 5406         }
 5407         fclose(fp_gr);
 5408      }
 5409   }
 5410   
 5411   @ Display the maximum optical intensity detected in the grating.
 5412   
 5413   @<Print information on maximum optical intensity in grating@>=
 5414   {
 5415      if (intensityinfo) {
 5416         for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
 5417         fprintf(stdout,"Summary of intra-grating intensities:\n");
 5418         fprintf(stdout,
 5419          "The maximum intensity %1.4e [W/m^2] (%1.4f GW/cm^2) was detected\n",
 5420          maxintens,maxintens*1.0e-13);
 5421         fprintf(stdout,
 5422          "in layer %ld. The maximum intensity was detected at a transmitted\n",
 5423          maxintens_layer);
 5424         fprintf(stdout,
 5425          "intensity of %1.4e [W/m^2] (%1.4f GW/cm^2), and at a transmitted\n",
 5426          maxintens_trintens,maxintens_trintens*1.0e-13);
 5427         fprintf(stdout,
 5428          "normalized ellipticity of S3/S0=%1.4f. ",maxintens_trellip);
 5429         fprintf(stdout,"(where S3/S0=1 for LCP, and -1\n""for RCP).");
 5430         fprintf(stdout,
 5431          "At this state, the calculated optical intensity incident to the\n");
 5432         fprintf(stdout,
 5433          "crystal was %1.4e [W/m^2] (%1.4f GW/cm^2), or %1.1f percent\n",
 5434          maxintens_inintens,maxintens_inintens*1.0e-13,
 5435          100.0*maxintens_inintens/maxintens);
 5436         fprintf(stdout,"of the maximum intra-grating optical intensity.\n");
 5437         fprintf(stdout,
 5438          "The calculated normalized incident ellipticity was %1.4f.\n",
 5439          maxintens_inellip);
 5440         fprintf(stdout,
 5441          "The intensity transmission was for this state %1.1f percent.\n",
 5442          100.0*maxintens_trintens/maxintens_inintens);
 5443         for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
 5444         if (saveintensityinfologfile) { /* also save log to file */
 5445            if ((intensinfologfile=fopen(intensinfologfilename,"w"))==NULL) {
 5446               fprintf(stderr,"%s: Could not open %s for intensity log!\n",
 5447                  progname,intensinfologfilename);
 5448               exit(FAILURE);
 5449            }
 5450            for (k=1;k<=32;k++) fprintf(intensinfologfile,(k<32?"-":"\n"));
 5451            fprintf(intensinfologfile,"Summary of intra-grating intensities:\n");
 5452            fprintf(intensinfologfile,
 5453             "Maximum intensity %1.4e [W/sq.m] (%1.4f GW/sq.cm) was detected\n",
 5454             maxintens,maxintens*1.0e-13);
 5455            fprintf(intensinfologfile,
 5456             "in layer %ld. Maximum intensity was detected at a transmitted\n",
 5457             maxintens_layer);
 5458            fprintf(intensinfologfile,
 5459             "intensity of %1.4e [W/sq.m] (%1.4f GW/sq.cm), and at transmitted\n",
 5460             maxintens_trintens,maxintens_trintens*1.0e-13);
 5461            fprintf(intensinfologfile,
 5462             "normalized ellipticity of S3/S0=%1.4f. ",maxintens_trellip);
 5463            fprintf(intensinfologfile,
 5464             "(where S3/S0=1 for LCP, and -1\n""for RCP). ");
 5465            fprintf(intensinfologfile,
 5466             "At this state, the calculated optical intensity incident to the\n");
 5467            fprintf(intensinfologfile,
 5468             "crystal was %1.4e [W/sq.m] (%1.4f GW/sq.cm), or %1.1f percent\n",
 5469             maxintens_inintens,maxintens_inintens*1.0e-13,
 5470             100.0*maxintens_inintens/maxintens);
 5471            fprintf(intensinfologfile,
 5472               "of the maximum intra-grating optical intensity.\n");
 5473            fprintf(intensinfologfile,
 5474             "The calculated normalized incident ellipticity was %1.4f.\n",
 5475             maxintens_inellip);
 5476            fprintf(intensinfologfile,
 5477             "The intensity transmission was for this state %1.1f percent.\n",
 5478             100.0*maxintens_trintens/maxintens_inintens);
 5479            fclose(intensinfologfile);
 5480            for (k=1;k<=32;k++) fprintf(intensinfologfile,(k<32?"-":"\n"));
 5481         }
 5482      }
 5483   }
 5484   
 5485   @* Routine for checking for numerical characters.
 5486   The |numeric()| routine takes one character |ch| as argument, and
 5487   returns 1 (``true'') if the character is a sign or numeric,
 5488   otherwise 0 (``false'') is returned. Notice that numerical fields
 5489   of the form ``.314159'' are not allowed or recognized here.
 5490   
 5491   @<Routine for checking for numerical characters@>=
 5492   int numeric(char ch) {
 5493      if ((ch=='0')||(ch=='1')||(ch=='2')||(ch=='3')||(ch=='4')||(ch=='5')
 5494         ||(ch=='6')||(ch=='7')||(ch=='8')||(ch=='9')||(ch=='+')||(ch=='-')) {
 5495         return(1); /* yes, this is a sign or numeric character */
 5496      } else {
 5497         return(0); /* no, this is not a sign or numeric character */
 5498      }
 5499   }
 5500   
 5501   @*Routine for initialization of Cantor type fractal gratings.
 5502   
 5503   @<Routine for initialization of Cantor type fractal gratings@>=
 5504   void init_cantor_fractal_grating(double *z,int indxmin,int indxmax,
 5505         double llmin,double llmax,double n1,double n2) {
 5506      int indxmid;
 5507      double dll;
 5508      if (indxmax-indxmin==1) {
 5509         z[indxmin]=llmin;
 5510         z[indxmax]=llmax;
 5511      } else if (indxmax-indxmin>=3) {
 5512         indxmid=(indxmin+indxmax)/2;
 5513         dll=(n2/(n1+2*n2))*(llmax-llmin);
 5514         init_cantor_fractal_grating(z,indxmin,indxmid,llmin,llmin+dll,n1,n2);
 5515         init_cantor_fractal_grating(z,indxmid+1,indxmax,llmax-dll,llmax,n1,n2);
 5516      } else {
 5517         fprintf(stderr,"%s: Error in indexes detected in routine %s",progname,
 5518            "init_cantor_fractal_grating()!\n");
 5519         fprintf(stderr,"%s: Please verify that the number of discrete layers\n",
 5520            progname);
 5521         fprintf(stderr,"%s: in the grating is N-1, where N is an integer"
 5522            " power of 2.\n",progname);
 5523         exit(FAILURE);
 5524      }
 5525   }
 5526   
 5527   @* Routines for removing preceding path of filenames.
 5528   In this block all routines related to removing preceding path strings go.
 5529   Not really fancy programming, and no contribution to any increase of numerical
 5530   efficiency or precision; just for the sake of keeping a tidy terminal output
 5531   of the program. The |strip_away_path()| routine is typically called when
 5532   initializing the program name string |progname| from the command line string
 5533   |argv[0]|, and is typically located in the blocks related to parsing of the
 5534   command line options.
 5535   
 5536   @<Routines for removing preceding path of filenames@>=
 5537      @<Routine for checking valid path characters@>@;
 5538      @<Routine for stripping away path string@>@;
 5539   
 5540   @ Checking for a valid path character.
 5541   The |pathcharacter| routine takes one character |ch| as argument, and returns
 5542   1 (``true'') if the character is valid character of a path string, otherwise 0
 5543   (``false'') is returned. The |isalnum| requires \.{ctype.h}.
 5544   
 5545   @<Routine for checking valid path characters@>=
 5546   short pathcharacter(int ch) {
 5547      return(isalnum(ch)||(ch=='.')||(ch=='/')||(ch=='\\')||(ch=='_')||
 5548          (ch=='-')||(ch=='+'));
 5549   }
 5550   
 5551   @ Stripping path string from a file name.
 5552   The |strip_away_path| routine takes a character string |filename| as
 5553   argument, and returns a pointer to the same string but without any
 5554   preceding path segments. This routine is, for example, useful for
 5555   removing paths from program names as parsed from the command line.
 5556   
 5557   @<Routine for stripping away path string@>=
 5558   char *strip_away_path(char filename[]) {
 5559      int j,k=0;
 5560      while (pathcharacter(filename[k])) k++;
 5561      j=(--k); /* this is the uppermost index of the full path+file string */
 5562      while (isalnum((int)(filename[j]))) j--;
 5563      j++; /* this is the lowermost index of the stripped file name */
 5564      return(&filename[j]);
 5565   }
 5566   
 5567   @* Routines for generation of random numbers. The |ran1()| routine is
 5568   taken from Numerical Recipes in C, 2nd ed.~(Cambridge University Press,
 5569   New York, 1994).
 5570   
 5571   @<Routines for generation of random numbers@>=
 5572   #define IA 16807
 5573   #define IM 2147483647
 5574   #define AM (1.0/IM)
 5575   #define IQ 127773
 5576   #define IR 2836
 5577   #define NTAB 32
 5578   #define NDIV (1+(IM-1)/NTAB)
 5579   #define EPS 1.2e-7
 5580   #define RNMX (1.0-EPS)
 5581   
 5582   float ran1(long *idum)
 5583   {
 5584      int j;
 5585      long k;
 5586      static long iy=0;
 5587      static long iv[NTAB];
 5588      float temp;
 5589   
 5590      if (*idum <= 0 || !iy) {
 5591         if (-(*idum) < 1) *idum=1;
 5592         else *idum = -(*idum);
 5593         for (j=NTAB+7;j>=0;j--) {
 5594            k=(*idum)/IQ;
 5595            *idum=IA*(*idum-k*IQ)-IR*k;
 5596            if (*idum < 0) *idum += IM;
 5597            if (j < NTAB) iv[j] = *idum;
 5598         }
 5599         iy=iv[0];
 5600      }
 5601      k=(*idum)/IQ;
 5602      *idum=IA*(*idum-k*IQ)-IR*k;
 5603      if (*idum < 0) *idum += IM;
 5604      j=iy/NDIV;
 5605      iy=iv[j];
 5606      iv[j] = *idum;
 5607      if ((temp=AM*iy) > RNMX) return RNMX;
 5608      else return temp;
 5609   }
 5610   #undef IA
 5611   #undef IM
 5612   #undef AM
 5613   #undef IQ
 5614   #undef IR
 5615   #undef NTAB
 5616   #undef NDIV
 5617   #undef EPS
 5618   #undef RNMX
 5619   
 5620   @* Routines for doing complex arithmetics. By using the data structure
 5621   |dcomplex|, which here is the basic construct for complex numbers,
 5622   containing real and imaginary parts in double precision, several
 5623   routines for doing arithmetics with this representation have been
 5624   implemented.
 5625   
 5626   @<Routines for complex arithmetics@>=
 5627      @<Complex number@>@;
 5628      @<Complex conjugation@>@;
 5629      @<Absolute value of complex number@>@;
 5630      @<Squared absolute value of complex number@>@;
 5631      @<Complex addition@>@;
 5632      @<Complex subtraction@>@;
 5633      @<Complex multiplication@>@;
 5634      @<Complex division@>@;
 5635      @<Complex square root@>@;
 5636      @<Complex exponentiation@>@;
 5637   
 5638   @ The function |complex(a,b)| takes two real valued arguments |a| and |b|
 5639   as input, and returns the complex number $|c|=|a|+i|b|$.
 5640   This basic construct is useful for storing temporary results, and
 5641   for internal use in routines dealing with complex arithmetics.
 5642   
 5643   @<Complex number@>=
 5644   dcomplex complex(double re, double im) {
 5645      dcomplex c;
 5646      c.r=re;
 5647      c.i=im;
 5648      return c;
 5649   }
 5650   
 5651   @ The function |conjg(z)| takes a complex valued argument |z| of
 5652   type |dcomplex| as input, and returns the complex conjugate
 5653   $\bar{|z|}=\re(|z|)-i\im(|z|)$.
 5654   
 5655   @<Complex conjugation@>=
 5656   dcomplex conjg(dcomplex z) {
 5657      dcomplex c;
 5658      c.r=z.r;
 5659      c.i=-z.i;
 5660      return c;
 5661   }
 5662   
 5663   @ The function |cdabs(z)| takes a complex valued argument |z| as input,
 5664   and returns the absolute value
 5665   $\vert|z|\vert=[\re(|z|)^2+\im(|z|)^2]^{1/2}$.
 5666   
 5667   @<Absolute value of complex number@>=
 5668   double cdabs(dcomplex z) {
 5669      double x,y,c,tmp;
 5670      x=fabs(z.r);
 5671      y=fabs(z.i);
 5672      if (x==0.0)
 5673         c=y;
 5674      else if (y==0.0)
 5675         c=x;
 5676      else if (x>y) {
 5677         tmp=y/x;
 5678         c=x*sqrt(1.0+tmp*tmp);
 5679      } else {
 5680         tmp=x/y;
 5681         c=y*sqrt(1.0+tmp*tmp);
 5682      }
 5683      return c;
 5684   }
 5685   
 5686   @ The function |cabs2(z)| takes a complex valued argument |z| as input, and
 5687   returns the squared absolute value $\vert|z|\vert^2=\re(|z|)^2+\im(|z|)^2$.
 5688   This function is identical to the |cdabs(z)| function, with the exception that
 5689   the squared result is returned.
 5690   
 5691   @<Squared absolute value of complex number@>=
 5692   double cabs2(dcomplex z) {
 5693      double x,y,c,tmp;
 5694      x=fabs(z.r);
 5695      y=fabs(z.i);
 5696      if (x==0.0)
 5697         c=y*y;
 5698      else if (y==0.0)
 5699         c=x*x;
 5700      else if (x>y) {
 5701         tmp=y/x;
 5702         c=x*x*(1.0+tmp*tmp);
 5703      } else {
 5704         tmp=x/y;
 5705         c=y*y*(1.0+tmp*tmp);
 5706      }
 5707      return c;
 5708   }
 5709   
 5710   @ The function |cadd(a,b)| takes complex valued arguments |a| and |b|
 5711   as inputs, and returns the complex valued sum $|a|+|b|$.
 5712   
 5713   @<Complex addition@>=
 5714   dcomplex cadd(dcomplex a, dcomplex b) {
 5715      dcomplex c;
 5716      c.r=a.r+b.r;
 5717      c.i=a.i+b.i;
 5718      return c;
 5719   }
 5720   
 5721   @ The function |csub(a,b)| takes complex valued arguments |a| and |b| as
 5722   inputs, and returns the complex valued difference $|a|-|b|$.
 5723   
 5724   @<Complex subtraction@>=
 5725   dcomplex csub(dcomplex a, dcomplex b) {
 5726      dcomplex c;
 5727      c.r=a.r-b.r;
 5728      c.i=a.i-b.i;
 5729      return c;
 5730   }
 5731   
 5732   @ When dealing with multiplication involving complex numbers, the case
 5733   where one of the numbers is entirely real is distinguished from the
 5734   general multiplication by two complex valued numbers, in order to speed
 5735   up the multiplication somewhat.
 5736   
 5737   @<Complex multiplication@>=
 5738   @<Multiplication by two complex numbers@>@;
 5739   @<Multiplication by real and complex numbers@>@;
 5740   
 5741   @ The function |cmul(a,b)| takes complex valued arguments |a| and |b|
 5742   as inputs, and returns the complex valued product |ab|.
 5743   
 5744   @<Multiplication by two complex numbers@>=
 5745   dcomplex cmul(dcomplex a, dcomplex b) {
 5746      dcomplex c;
 5747      c.r=a.r*b.r-a.i*b.i;
 5748      c.i=a.i*b.r+a.r*b.i;
 5749      return c;
 5750   }
 5751   
 5752   @ The function |rcmul(a,b)| takes a real valued argument |a| and
 5753   a complex valued arguments |b| as inputs, and returns the
 5754   complex valued product $|ab| = |a|\re(|b|) + i|a|\im(|b|)$.
 5755   
 5756   @<Multiplication by real and complex numbers@>=
 5757   dcomplex rcmul(double a, dcomplex b) {
 5758      dcomplex c;
 5759      c.r=a*b.r;
 5760      c.i=a*b.i;
 5761      return c;
 5762   }
 5763   
 5764   @ When dealing with division involving complex numbers, the case
 5765   where the denominator is entirely real is distinguished from the
 5766   general division by two complex valued numbers, in order to speed
 5767   up the division somewhat.
 5768   
 5769   @<Complex division@>=
 5770      @<Division by complex numbers@>@;
 5771      @<Division by complex and real number@>@;
 5772   
 5773   @ The function |cdiv(a,b)| takes complex valued arguments |a| and |b|
 5774   as inputs, and returns the complex valued quote $|a|/|b|$.
 5775   If the denominator is found to be real, this routine speed up the
 5776   division in similar to the |crdiv| routine, by instead applying the rules
 5777   of real-valued division.
 5778   
 5779   @<Division by complex numbers@>=
 5780   dcomplex cdiv(dcomplex a, dcomplex b) {
 5781      dcomplex c;
 5782      double r,den;
 5783      if (cdabs(b)>0.0) {
 5784         if (fabs(b.i)==0.0) {
 5785            c.r=a.r/b.r;
 5786            c.i=a.i/b.r;
 5787         } else {
 5788            if (fabs(b.r) >= fabs(b.i)) {
 5789               r=b.i/b.r;
 5790               den=b.r+r*b.i;
 5791               c.r=(a.r+r*a.i)/den;
 5792               c.i=(a.i-r*a.r)/den;
 5793            } else {
 5794               r=b.r/b.i;
 5795               den=b.i+r*b.r;
 5796               c.r=(a.r*r+a.i)/den;
 5797               c.i=(a.i*r-a.r)/den;
 5798            }
 5799         }
 5800      } else {
 5801         fprintf(stderr,"Error in cdiv(): Division by zero!\n");
 5802         exit(FAILURE);
 5803      }
 5804      return c;
 5805   }
 5806   
 5807   @ The function |crdiv(a,b)| takes a complex valued argument |a| of
 5808   and a real valued argument |b| as inputs, and returns the complex
 5809   valued quote $|a|/|b| = \re(|a|)/|b| + i\im(|a|)/|b|$.
 5810   
 5811   @<Division by complex and real number@>=
 5812   dcomplex crdiv(dcomplex a, double b) {
 5813      dcomplex c;
 5814      if (fabs(b)>0.0) {
 5815         c.r=a.r/b;
 5816         c.i=a.i/b;
 5817      } else {
 5818         fprintf(stderr,"Error in crdiv(): Division by zero!\n");
 5819         exit(FAILURE);
 5820      }
 5821      return c;
 5822   }
 5823   
 5824   @ The function |csqrt(z)| takes a complex valued argument |z| as input
 5825   and returns the complex valued square root $|z|{}^{1/2}$.
 5826   
 5827   @<Complex square root@>=
 5828   dcomplex csqrt(dcomplex z) {
 5829      dcomplex c;
 5830      double x,y,w,r;
 5831      if ((z.r==0.0)&&(z.i==0.0)) {
 5832         c.r=0.0;
 5833         c.i=0.0;
 5834         return c;
 5835      } else {
 5836         x=fabs(z.r);
 5837         y=fabs(z.i);
 5838         if (x>=y) {
 5839            r=y/x;
 5840            w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r)));
 5841         } else {
 5842            r=x/y;
 5843            w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r)));
 5844         }
 5845         if (z.r>=0.0) {
 5846            c.r=w;
 5847            c.i=0.5*z.i/w;
 5848         } else {
 5849            c.i=((z.i>=0)?w:-w);
 5850            c.r=0.5*z.i/c.i;
 5851         }
 5852         return c;
 5853      }
 5854   }
 5855   
 5856   @ For complex exponentiation, we distinguish between the case when
 5857   the argument is complex valued, with nonzero real and imaginary parts,
 5858   and the case where the argument is entirely imaginary.
 5859   In the former case, the |cexp| routine should be used, while in
 5860   the latter case, the |crexpi| routine is more appropriate.
 5861   
 5862   @<Complex exponentiation@>=
 5863      @<Exponentiation by complex number@>@;
 5864      @<Exponentiation by imaginary number@>@;
 5865   
 5866   @ The function |cexp(a)| takes a complex valued argument |a| as input
 5867   and returns the complex valued ex\-po\-nen\-tial
 5868   $\exp(a)=\exp(\re(a))[\cos(\im(|a|))+i\sin(\im(|a|))]$.
 5869   
 5870   @<Exponentiation by complex number@>=
 5871   dcomplex cexp(dcomplex a) {
 5872      dcomplex c;
 5873      double tmp=exp(a.r);
 5874      c.r=tmp*cos(a.i);
 5875      c.i=tmp*sin(a.i);
 5876      return c;
 5877   }
 5878   
 5879   @ The function |crexpi(a)| takes a real valued argument |a| as input and
 5880   returns the complex valued expo\-nen\-tial $\exp(i|a|)=\cos(|a|)+i\sin(|a|)$.
 5881   
 5882   @<Exponentiation by imaginary number@>=
 5883   dcomplex crexpi(double a) {
 5884      dcomplex c;
 5885      c.r=cos(a);
 5886      c.i=sin(a);
 5887      return c;
 5888   }
 5889   
 5890   @*Subroutines for memory allocation. Here follows the routines for memory
 5891   allocation and deallocation of double precision real and complex valued
 5892   vectors, as used for storing the optical field distribution in the grating,
 5893   the refractive index distribution of the grating, etc.
 5894   
 5895   @<Routines for memory allocation of vectors@>=
 5896      @<Allocation of real-valued vectors@>@;
 5897      @<Allocation of complex-valued vectors@>@;
 5898      @<Deallocation of real-valued vectors@>@;
 5899      @<Deallocation of complex-valued vectors@>@;
 5900   
 5901   @ The |dvector| routine allocate a real-valued vector of double precision,
 5902   with vector index ranging from |nl| to |nh|, while the |dcvector|
 5903   routine allocate a complex-valued vector of double precision, with
 5904   vector index ranging from |nl| to |nh|.
 5905   
 5906   @<Allocation of real-valued vectors@>=
 5907   double *dvector(long nl, long nh) {
 5908      double *v;
 5909      v=(double *)malloc((size_t) ((nh-nl+2)*sizeof(double)));
 5910      if (!v) {
 5911         fprintf(stderr,"Error: Allocation failure in dvector()\n");
 5912         exit(FAILURE);
 5913      }
 5914      return v-nl+1;
 5915   }
 5916   
 5917   @ The |dcvector| routine allocate a complex-valued vector of double
 5918   precision, with vector index ranging from |nl| to |nh|. The basic
 5919   building type of the obtained complex valued vector is the globally
 5920   declarated |dcomplex| data structure.
 5921   
 5922   @<Allocation of complex-valued vectors@>=
 5923   dcomplex *dcvector(long nl, long nh) {
 5924      dcomplex *v;
 5925      v=(dcomplex *)malloc((size_t) ((nh-nl+2)*sizeof(dcomplex)));
 5926      if (!v) {
 5927         fprintf(stderr,"Error: Allocation failure in dcvector()\n");
 5928         exit(FAILURE);
 5929      }
 5930      return v-nl+1;
 5931   }
 5932   
 5933   @ The |free_dvector| routine release the memory occupied by the
 5934   real-valued vector |v[nl..nh]|.
 5935   
 5936   @<Deallocation of real-valued vectors@>=
 5937   void free_dvector(double *v, long nl, long nh) {
 5938      free((char*) (v+nl-1));
 5939   }
 5940   
 5941   @ The |free_dcvector| routine release the memory occupied by the
 5942   complex-valued vector |v[nl..nh]|.
 5943   
 5944   @<Deallocation of complex-valued vectors@>=
 5945   void free_dcvector(dcomplex *v, long nl, long nh) {
 5946      free((char*) (v+nl-1));
 5947   }
 5948   
 5949   @*Parsing command line options. All input parameters are passed to the
 5950   program through command line options and arguments to the program.
 5951   The syntax of command line options is listed
 5952   whenever the program is invoked without any options, or whenever any of the
 5953   \.{--help} or \.{-h} options are specified at startup.
 5954   
 5955   @<Parse command line for parameter values@>=
 5956   {
 5957      progname=strip_away_path(argv[0]);
 5958      fprintf(stdout,"This is %s v.%s. %s\n",progname,VERSION,COPYRIGHT);
 5959      no_arg=argc;
 5960      while(--argc) {
 5961         if(!strcmp(argv[no_arg-argc],"-o") ||
 5962            !strcmp(argv[no_arg-argc],"--outputfile")) {
 5963            --argc;
 5964            strcpy(outfilename,argv[no_arg-argc]);
 5965         } else if(!strcmp(argv[no_arg-argc],"-w") ||
 5966            !strcmp(argv[no_arg-argc],"--writegratingfile")) {
 5967            --argc;
 5968            strcpy(gratingfilename,argv[no_arg-argc]);
 5969            writegratingtofile=1;
 5970         } else if(!strcmp(argv[no_arg-argc],"--displaysurrmedia")) {
 5971            display_surrounding_media=(display_surrounding_media?0:1);
 5972         } else if(!strcmp(argv[no_arg-argc],"-a") ||
 5973                   !strcmp(argv[no_arg-argc],"--apodize")) {
 5974            @<Parse apodization options@>;
 5975         } else if(!strcmp(argv[no_arg-argc],"--phasejump")) {
 5976            @<Parse phase jump options@>;
 5977         } else if(!strcmp(argv[no_arg-argc],"--fieldevolution")) {
 5978            @<Parse field evolution saving options@>;
 5979         } else if(!strcmp(argv[no_arg-argc],"--intensityevolution")) {
 5980            --argc;
 5981            if(!sscanf(argv[no_arg-argc],"%lf",&ievolambda)) {
 5982               fprintf(stderr,"%s: Error in '--intensityevolution' option.\n",
 5983                       progname);
 5984               exit(FAILURE);
 5985            }
 5986            --argc;
 5987            strcpy(intensityevofilename,argv[no_arg-argc]);
 5988            intensityevoflag=1;
 5989         } else if(!strcmp(argv[no_arg-argc],"--spectrumfile")) {
 5990            --argc;
 5991            strcpy(spectrumfilename,argv[no_arg-argc]);
 5992         } else if(!strcmp(argv[no_arg-argc],"--stokesspectrum")) {
 5993            stokes_parameter_spectrum=1;
 5994         } else if(!strcmp(argv[no_arg-argc],"--trmtraject")) {
 5995            --argc;
 5996            strcpy(trmtraject_filename,argv[no_arg-argc]);
 5997            trmtraject_specified=1;
 5998         } else if(!strcmp(argv[no_arg-argc],"--intensityspectrumfile")) {
 5999            --argc;
 6000            strcpy(intensity_reflection_spectrumfilename,argv[no_arg-argc]);
 6001            strcpy(intensity_transmission_spectrumfilename,argv[no_arg-argc]);
 6002            strcpy(intensity_check_spectrumfilename,argv[no_arg-argc]);
 6003            sprintf(intensity_reflection_spectrumfilename,"%s.irsp.dat",
 6004               intensity_reflection_spectrumfilename);
 6005            sprintf(intensity_transmission_spectrumfilename,"%s.itsp.dat",
 6006               intensity_transmission_spectrumfilename);
 6007            sprintf(intensity_check_spectrumfilename,"%s.chec.dat",
 6008               intensity_check_spectrumfilename);
 6009   
 6010         } else if(!strcmp(argv[no_arg-argc],"--logarithmicspectrum")) {
 6011            save_dbspectra=1;
 6012   
 6013         } else if(!strcmp(argv[no_arg-argc],"-v") ||
 6014                   !strcmp(argv[no_arg-argc],"--verbose")) {
 6015            verbose=(verbose?0:1);
 6016   
 6017         } else if(!strcmp(argv[no_arg-argc],"--scale_stokesparams")) {
 6018            scale_stokesparams=1;
 6019            --argc;
 6020            if(!sscanf(argv[no_arg-argc],"%lf",&stoke_scalefactor)) {
 6021               fprintf(stderr,"%s: Error in '--scale_stokesparams' option.\n",\
 6022                  progname);
 6023               exit(FAILURE);
 6024            }
 6025         } else if(!strcmp(argv[no_arg-argc],"--intensityinfo")) {
 6026            intensityinfo=(intensityinfo?0:1);
 6027         } else if(!strcmp(argv[no_arg-argc],"--intensityinfologfile")) {
 6028            intensityinfo=1;
 6029            saveintensityinfologfile=1;
 6030            --argc;
 6031            strcpy(intensinfologfilename,argv[no_arg-argc]);
 6032         } else if(!strcmp(argv[no_arg-argc],"--gyroperturb")) {
 6033            @<Parse gyration constant perturbation options@>;
 6034         } else if(!strcmp(argv[no_arg-argc],"--normalize_length_to_um")) {
 6035            normalize_length_to_micrometer=(normalize_length_to_micrometer?0:1);
 6036         } else if(!strcmp(argv[no_arg-argc],"--normalize_intensity")) {
 6037            normalize_intensity=(normalize_intensity?0:1);
 6038         } else if(!strcmp(argv[no_arg-argc],"--normalize_ellipticity")) {
 6039            normalize_ellipticity=(normalize_ellipticity?0:1);
 6040         } else if(!strcmp(argv[no_arg-argc],"--normalizedrepresentation")) {
 6041            normalize_internally=(normalize_internally?0:1);
 6042         } else if(!strcmp(argv[no_arg-argc],"-r") ||
 6043            !strcmp(argv[no_arg-argc],"--random")) {
 6044            randomdistribution=(randomdistribution?0:1);
 6045         } else if(!strcmp(argv[no_arg-argc],"-h") ||
 6046            !strcmp(argv[no_arg-argc],"--help")) {
 6047            showsomehelp();
 6048         } else if(!strcmp(argv[no_arg-argc],"-g") ||
 6049            !strcmp(argv[no_arg-argc],"--grating")) {
 6050            --argc;
 6051            if(!strcmp(argv[no_arg-argc],"stepwise")) {
 6052               @<Parse for stepwise grating options@>@;
 6053            } else if(!strcmp(argv[no_arg-argc],"sinusoidal")) {
 6054               @<Parse for sinusoidal grating options@>@;
 6055            } else if(!strcmp(argv[no_arg-argc],"chirped")) {
 6056               @<Parse for chirped grating options@>@;
 6057            } else if(!strcmp(argv[no_arg-argc],"fractal")) {
 6058               @<Parse for fractal grating options@>@;
 6059            } else {
 6060               fprintf(stderr,"%s: Error in '-g' or '--grating' option.\n",
 6061                  progname);
 6062               fprintf(stderr,"%s: (No valid grating type found!)\n",progname);
 6063               exit(FAILURE);
 6064            }
 6065         } else if((!strcmp(argv[no_arg-argc],"-L"))||
 6066                   (!strcmp(argv[no_arg-argc],"--gratinglength"))) {
 6067            --argc;
 6068            if(!sscanf(argv[no_arg-argc],"%lf",&ll)) {
 6069               fprintf(stderr,"%s: Error in '-L' option.\n",progname);
 6070               exit(FAILURE);
 6071            }
 6072         } else if(!strcmp(argv[no_arg-argc],"--modifylayer")) {
 6073            @<Parse for options for modified layer of grating structure@>@;
 6074         } else if(!strcmp(argv[no_arg-argc],"--refindsurr")) {
 6075            --argc;
 6076            if(!sscanf(argv[no_arg-argc],"%lf",&nsurr)) {
 6077               fprintf(stderr,"%s: Error in '--refindsurr' option.\n",progname);
 6078               exit(FAILURE);
 6079            }
 6080         } else if(!strcmp(argv[no_arg-argc],"--trmintensity")) {
 6081            @<Parse the command line for transmitted intensity range@>@;
 6082         } else if(!strcmp(argv[no_arg-argc],"--trmellipticity")) {
 6083            @<Parse the command line for transmitted ellipticity range@>@;
 6084         } else if(!strcmp(argv[no_arg-argc],"--lambdastart")) {
 6085            --argc;
 6086            if(!sscanf(argv[no_arg-argc],"%lf",&lambdastart)) {
 6087               fprintf(stderr,"%s: Error in '--lambdastart' option.\n",progname);
 6088               exit(FAILURE);
 6089            }
 6090         } else if(!strcmp(argv[no_arg-argc],"--lambdastop")) {
 6091            --argc;
 6092            if(!sscanf(argv[no_arg-argc],"%lf",&lambdastop)) {
 6093               fprintf(stderr,"%s: Error in '--lambdastop' option.\n",progname);
 6094               exit(FAILURE);
 6095            }
 6096         } else if(!strcmp(argv[no_arg-argc],"--wlenlinz")) {
 6097            chirpflag=1;
 6098         } else if(!strcmp(argv[no_arg-argc],"--freqlinz")) {
 6099            chirpflag=0;
 6100         } else if(!strcmp(argv[no_arg-argc],"-N")) {
 6101            --argc;
 6102            if(!sscanf(argv[no_arg-argc],"%ld",&nn)) {
 6103               fprintf(stderr,"%s: Error in '-N' option.\n",progname);
 6104               exit(FAILURE);
 6105            }
 6106         } else if(!strcmp(argv[no_arg-argc],"-M")) {
 6107            --argc;
 6108            if(!sscanf(argv[no_arg-argc],"%ld",&mm)) {
 6109               fprintf(stderr,"%s: Error in '-M' option.\n",progname);
 6110               exit(FAILURE);
 6111            }
 6112         } else {
 6113            fprintf(stderr,"%s: Specified option invalid!\n",progname);
 6114            showsomehelp();
 6115            exit(FAILURE);
 6116         }
 6117      }
 6118      @<Create outfile suffixes@>@;
 6119      @<Display parameters parsed from the command line@>@;
 6120   }
 6121   
 6122   @ Create suffixes for output filenames. The output files for the Stokes
 6123   parameters are named according to the convention that....
 6124   
 6125   @<Create outfile suffixes@>=
 6126   {
 6127      sprintf(outfilename_s0,"%s.s0.dat",outfilename);
 6128      sprintf(outfilename_s1,"%s.s1.dat",outfilename);
 6129      sprintf(outfilename_s2,"%s.s2.dat",outfilename);
 6130      sprintf(outfilename_s3,"%s.s3.dat",outfilename);
 6131      sprintf(outfilename_v0,"%s.v0.dat",outfilename);
 6132      sprintf(outfilename_v1,"%s.v1.dat",outfilename);
 6133      sprintf(outfilename_v2,"%s.v2.dat",outfilename);
 6134      sprintf(outfilename_v3,"%s.v3.dat",outfilename);
 6135      sprintf(outfilename_w0,"%s.w0.dat",outfilename);
 6136      sprintf(outfilename_w1,"%s.w1.dat",outfilename);
 6137      sprintf(outfilename_w2,"%s.w2.dat",outfilename);
 6138      sprintf(outfilename_w3,"%s.w3.dat",outfilename);
 6139   }
 6140   
 6141   @ Parse the command line for options related to apodization~[15] of the spatial
 6142   modulation of the refractive index and gyration coefficient.
 6143   
 6144   @<Parse apodization options@>=
 6145   {
 6146      apodize=1;
 6147      --argc;
 6148      if(!sscanf(argv[no_arg-argc],"%lf",&apolength)) {
 6149         fprintf(stderr,"%s: Error in '--apodize' option.\n",progname);
 6150         exit(FAILURE);
 6151      }
 6152   }
 6153   
 6154   @ Parse the command line for options related to discrete phase jump in
 6155   the spatial modulation of the refractive index and gyration coefficient.
 6156   
 6157   @<Parse phase jump options@>=
 6158   {
 6159      phasejump=1;
 6160      --argc;
 6161      if(!sscanf(argv[no_arg-argc],"%lf",&phasejumpangle)) {
 6162         fprintf(stderr,"%s: Error in 1st arg of '--phasejump' option.\n",
 6163            progname);
 6164         exit(FAILURE);
 6165      }
 6166      --argc;
 6167      if(!sscanf(argv[no_arg-argc],"%lf",&phasejumpposition)) {
 6168         fprintf(stderr,"%s: Error in 2nd arg of '--phasejump' option.\n",
 6169            progname);
 6170         exit(FAILURE);
 6171      }
 6172   }
 6173   
 6174   @ Parse the command line for options related to a Lorentzian perturbation
 6175   of the magneto-optical gyration coefficient of the grating.
 6176   
 6177   @<Parse gyration constant perturbation options@>=
 6178   {
 6179      perturbed_gyration_constant=1;
 6180      --argc;
 6181      if(!sscanf(argv[no_arg-argc],"%lf",&gyroperturb_position)) {
 6182         fprintf(stderr,"%s: Error in '--gyroperturb' option.\n",progname);
 6183         exit(FAILURE);
 6184      }
 6185      --argc;
 6186      if(!sscanf(argv[no_arg-argc],"%lf",&gyroperturb_amplitude)) {
 6187         fprintf(stderr,"%s: Error in '--gyroperturb' option.\n",progname);
 6188         exit(FAILURE);
 6189      }
 6190      --argc;
 6191      if(!sscanf(argv[no_arg-argc],"%lf",&gyroperturb_width)) {
 6192         fprintf(stderr,"%s: Error in '--gyroperturb' option.\n",progname);
 6193         exit(FAILURE);
 6194      }
 6195   }
 6196   
 6197   @ Parse the command line for options related to saving the intra grating
 6198   optical field spatial evolution to file.
 6199   If Stokes parameters are preferred for the output of the spatial
 6200   intra-grating field evolution, the specified filename will be
 6201   used as the base name for the output file; the suffixes
 6202   \.{.s0.dat}, \.{.s1.dat}, \.{.s2.dat}, and \.{.s3.dat} will then be
 6203   appended to the base name in order to keep track of them.
 6204   
 6205   @<Parse field evolution saving options@>=
 6206   {
 6207      --argc;
 6208      if (!strcmp(argv[no_arg-argc],"efield")) {
 6209         fieldevoflag_efield=1;
 6210      } else if (!strcmp(argv[no_arg-argc],"stoke")) {
 6211         fieldevoflag_stoke=1;
 6212      } else {
 6213         fprintf(stderr,
 6214            "%s: Unknown field evolution flag '%s' in second argument of\n"
 6215            " --fieldevolution option.\n",progname,argv[no_arg-argc]);
 6216         exit(FAILURE);
 6217      }
 6218      --argc;
 6219      if(!sscanf(argv[no_arg-argc],"%ld",&nne)) {
 6220         fprintf(stderr,"%s: Error in '--fieldevolution' option.\n",
 6221            progname);
 6222         exit(FAILURE);
 6223      }
 6224      --argc;
 6225      strcpy(fieldevofilename,argv[no_arg-argc]);
 6226      fieldevoflag=1; /* Indicate that the field evolution shold be saved */
 6227      if (fieldevoflag_stoke) { /* Stokes parameter output preferred */
 6228         sprintf(fieldevofilename_s0,"%s.s0.dat",fieldevofilename);
 6229         sprintf(fieldevofilename_s1,"%s.s1.dat",fieldevofilename);
 6230         sprintf(fieldevofilename_s2,"%s.s2.dat",fieldevofilename);
 6231         sprintf(fieldevofilename_s3,"%s.s3.dat",fieldevofilename);
 6232      }
 6233   }
 6234   
 6235   @ Parse the command line for options related to the initiation of a stepwise
 6236   grating, consisting of a set of stacked layers.
 6237   
 6238   @<Parse for stepwise grating options@>=
 6239   {
 6240      strcpy(gratingtype,argv[no_arg-argc]);
 6241      --argc;
 6242      if(!strcmp(argv[no_arg-argc],"twolevel")) {
 6243         strcpy(gratingsubtype,argv[no_arg-argc]);
 6244         --argc;
 6245         if(strcmp(argv[no_arg-argc],"t1")) {
 6246            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6247            fprintf(stderr,"%s: (Expecting string 't1').\n",progname);
 6248            exit(FAILURE);
 6249         }
 6250         --argc;
 6251         if(!sscanf(argv[no_arg-argc],"%lf",&t1)) {
 6252            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6253            fprintf(stderr,"%s: (Could not read data for t1).\n",progname);
 6254            exit(FAILURE);
 6255         }
 6256         --argc;
 6257         if(strcmp(argv[no_arg-argc],"t2")) {
 6258            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6259            fprintf(stderr,"%s: (Expecting string 't2').\n",progname);
 6260            exit(FAILURE);
 6261         }
 6262         --argc;
 6263         if(!sscanf(argv[no_arg-argc],"%lf",&t2)) {
 6264            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6265            fprintf(stderr,"%s: (Could not read data for t2).\n",progname);
 6266            exit(FAILURE);
 6267         }
 6268         --argc;
 6269         if(strcmp(argv[no_arg-argc],"n1")) {
 6270            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6271            fprintf(stderr,"%s: (Expecting string 'n1').\n",progname);
 6272            exit(FAILURE);
 6273         }
 6274         --argc;
 6275         if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
 6276            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6277            fprintf(stderr,"%s: (Could not read data for n1).\n",progname);
 6278            exit(FAILURE);
 6279         }
 6280         --argc;
 6281         if(strcmp(argv[no_arg-argc],"n2")) {
 6282            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6283            fprintf(stderr,"%s: (Expecting string 'n2').\n",progname);
 6284            exit(FAILURE);
 6285         }
 6286         --argc;
 6287         if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
 6288            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6289            fprintf(stderr,"%s: (Could not read data for n2).\n",progname);
 6290            exit(FAILURE);
 6291         }
 6292         --argc;
 6293         if(strcmp(argv[no_arg-argc],"g1")) {
 6294            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6295            fprintf(stderr,"%s: (Expecting string 'g1').\n",progname);
 6296            exit(FAILURE);
 6297         }
 6298         --argc;
 6299         if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
 6300            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6301            fprintf(stderr,"%s: (Could not read data for g1).\n",progname);
 6302            exit(FAILURE);
 6303         }
 6304         --argc;
 6305         if(strcmp(argv[no_arg-argc],"g2")) {
 6306            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6307            fprintf(stderr,"%s: (Expecting string 'g2').\n",progname);
 6308            exit(FAILURE);
 6309         }
 6310         --argc;
 6311         if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
 6312            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6313            fprintf(stderr,"%s: (Could not read data for g2).\n",progname);
 6314            exit(FAILURE);
 6315         }
 6316         --argc;
 6317         if(strcmp(argv[no_arg-argc],"pe1")) {
 6318            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6319            fprintf(stderr,"%s: (Expecting string 'pe1').\n",progname);
 6320            exit(FAILURE);
 6321         }
 6322         --argc;
 6323         if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
 6324            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6325            fprintf(stderr,"%s: (Could not read data for pe1).\n",progname);
 6326            exit(FAILURE);
 6327         }
 6328         --argc;
 6329         if(strcmp(argv[no_arg-argc],"pe2")) {
 6330            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6331            fprintf(stderr,"%s: (Expecting string 'pe2').\n",progname);
 6332            exit(FAILURE);
 6333         }
 6334         --argc;
 6335         if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
 6336            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6337            fprintf(stderr,"%s: (Could not read data for pe2).\n",progname);
 6338            exit(FAILURE);
 6339         }
 6340         --argc;
 6341         if(strcmp(argv[no_arg-argc],"pm1")) {
 6342            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6343            fprintf(stderr,"%s: (Expecting string 'pm1').\n",progname);
 6344            exit(FAILURE);
 6345         }
 6346         --argc;
 6347         if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
 6348            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6349            fprintf(stderr,"%s: (Could not read data for pm1).\n",\
 6350               progname);
 6351            exit(FAILURE);
 6352         }
 6353         --argc;
 6354         if(strcmp(argv[no_arg-argc],"pm2")) {
 6355            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6356            fprintf(stderr,"%s: (Expecting string 'pm2').\n",progname);
 6357            exit(FAILURE);
 6358         }
 6359         --argc;
 6360         if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
 6361            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6362            fprintf(stderr,"%s: (Could not read data for pm2).\n",\
 6363               progname);
 6364            exit(FAILURE);
 6365         }
 6366         --argc;
 6367         if(strcmp(argv[no_arg-argc],"qe1")) {
 6368            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6369            fprintf(stderr,"%s: (Expecting string 'qe1').\n",progname);
 6370            exit(FAILURE);
 6371         }
 6372         --argc;
 6373         if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
 6374            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6375            fprintf(stderr,"%s: (Could not read data for qe1).\n",\
 6376               progname);
 6377            exit(FAILURE);
 6378         }
 6379         --argc;
 6380         if(strcmp(argv[no_arg-argc],"qe2")) {
 6381            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6382            fprintf(stderr,"%s: (Expecting string 'qe2').\n",progname);
 6383            exit(FAILURE);
 6384         }
 6385         --argc;
 6386         if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
 6387            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6388            fprintf(stderr,"%s: (Could not read data for qe2).\n",progname);
 6389            exit(FAILURE);
 6390         }
 6391         --argc;
 6392         if(strcmp(argv[no_arg-argc],"qm1")) {
 6393            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6394            fprintf(stderr,"%s: (Expecting string 'qm1').\n",progname);
 6395            exit(FAILURE);
 6396         }
 6397         --argc;
 6398         if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
 6399            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6400            fprintf(stderr,"%s: (Could not read data for qm1).\n",progname);
 6401            exit(FAILURE);
 6402         }
 6403         --argc;
 6404         if(strcmp(argv[no_arg-argc],"qm2")) {
 6405            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6406            fprintf(stderr,"%s: (Expecting string 'qm2').\n",progname);
 6407            exit(FAILURE);
 6408         }
 6409         --argc;
 6410         if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
 6411            fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
 6412            fprintf(stderr,"%s: (Could not read data for qm2).\n",progname);
 6413            exit(FAILURE);
 6414         }
 6415      } else {
 6416         fprintf(stderr,"%s: Error in '-g' or '--grating' option.\n",progname);
 6417         fprintf(stderr,"%s: (No valid stepwise grating type found!)\n",progname);
 6418         exit(FAILURE);
 6419      }
 6420   }
 6421   
 6422   @ Parse the command line for options related to the initiation of a sinusoidal
 6423   grating, consisting of a set of stacked layers.
 6424   
 6425   @<Parse for sinusoidal grating options@>=
 6426   {
 6427      strcpy(gratingtype,argv[no_arg-argc]);
 6428      --argc;
 6429      if(strcmp(argv[no_arg-argc],"n")) {
 6430         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6431         fprintf(stderr,"%s: (Expecting string 'n').\n",progname);
 6432         exit(FAILURE);
 6433      }
 6434      --argc;
 6435      if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
 6436         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6437         fprintf(stderr,"%s: (Could not read data for n [1st arg]).\n",progname);
 6438         exit(FAILURE);
 6439      }
 6440      --argc;
 6441      if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
 6442         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6443         fprintf(stderr,"%s: (Could not read data for n [2nd arg]).\n",progname);
 6444         exit(FAILURE);
 6445      }
 6446      --argc;
 6447      if(!sscanf(argv[no_arg-argc],"%lf",&nper)) {
 6448         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6449         fprintf(stderr,"%s: (Could not read data for n [3rd arg]).\n",progname);
 6450         exit(FAILURE);
 6451      }
 6452      --argc;
 6453      if(strcmp(argv[no_arg-argc],"g")) {
 6454         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6455         fprintf(stderr,"%s: (Expecting string 'g').\n",progname);
 6456         exit(FAILURE);
 6457      }
 6458      --argc;
 6459      if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
 6460         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6461         fprintf(stderr,"%s: (Could not read data for g [1st arg]).\n",progname);
 6462         exit(FAILURE);
 6463      }
 6464      --argc;
 6465      if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
 6466         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6467         fprintf(stderr,"%s: (Could not read data for g [2nd arg]).\n",progname);
 6468         exit(FAILURE);
 6469      }
 6470      --argc;
 6471      if(!sscanf(argv[no_arg-argc],"%lf",&gper)) {
 6472         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6473         fprintf(stderr,"%s: (Could not read data for g [3rd arg]).\n",progname);
 6474         exit(FAILURE);
 6475      }
 6476      --argc;
 6477      if(strcmp(argv[no_arg-argc],"pe")) {
 6478         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6479         fprintf(stderr,"%s: (Expecting string 'pe').\n",progname);
 6480         exit(FAILURE);
 6481      }
 6482      --argc;
 6483      if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
 6484         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6485         fprintf(stderr,"%s: (Could not read data for pe [1st arg]).\n",progname);
 6486         exit(FAILURE);
 6487      }
 6488      --argc;
 6489      if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
 6490         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6491         fprintf(stderr,"%s: (Could not read data for pe [2nd arg]).\n",progname);
 6492         exit(FAILURE);
 6493      }
 6494      --argc;
 6495      if(!sscanf(argv[no_arg-argc],"%lf",&peper)) {
 6496         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6497         fprintf(stderr,"%s: (Could not read data for pe [3rd arg]).\n",progname);
 6498         exit(FAILURE);
 6499      }
 6500      --argc;
 6501      if(strcmp(argv[no_arg-argc],"pm")) {
 6502         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6503         fprintf(stderr,"%s: (Expecting string 'pm').\n",progname);
 6504         exit(FAILURE);
 6505      }
 6506      --argc;
 6507      if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
 6508         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6509         fprintf(stderr,"%s: (Could not read data for pm [1st arg]).\n",progname);
 6510         exit(FAILURE);
 6511      }
 6512      --argc;
 6513      if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
 6514         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6515         fprintf(stderr,"%s: (Could not read data for pm [2nd arg]).\n",progname);
 6516         exit(FAILURE);
 6517      }
 6518      --argc;
 6519      if(!sscanf(argv[no_arg-argc],"%lf",&pmper)) {
 6520         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6521         fprintf(stderr,"%s: (Could not read data for pm [3rd arg]).\n",progname);
 6522         exit(FAILURE);
 6523      }
 6524      --argc;
 6525      if(strcmp(argv[no_arg-argc],"qe")) {
 6526         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6527         fprintf(stderr,"%s: (Expecting string 'qe').\n",progname);
 6528         exit(FAILURE);
 6529      }
 6530      --argc;
 6531      if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
 6532         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6533         fprintf(stderr,"%s: (Could not read data for qe [1st arg]).\n",progname);
 6534         exit(FAILURE);
 6535      }
 6536      --argc;
 6537      if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
 6538         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6539         fprintf(stderr,"%s: (Could not read data for qe [2nd arg]).\n",progname);
 6540         exit(FAILURE);
 6541      }
 6542      --argc;
 6543      if(!sscanf(argv[no_arg-argc],"%lf",&qeper)) {
 6544         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6545         fprintf(stderr,"%s: (Could not read data for qe [3rd arg]).\n",progname);
 6546         exit(FAILURE);
 6547      }
 6548      --argc;
 6549      if(strcmp(argv[no_arg-argc],"qm")) {
 6550         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6551         fprintf(stderr,"%s: (Expecting string 'qm').\n",progname);
 6552         exit(FAILURE);
 6553      }
 6554      --argc;
 6555      if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
 6556         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6557         fprintf(stderr,"%s: (Could not read data for qm [1st arg]).\n",progname);
 6558         exit(FAILURE);
 6559      }
 6560      --argc;
 6561      if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
 6562         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6563         fprintf(stderr,"%s: (Could not read data for qm [2nd arg]).\n",progname);
 6564         exit(FAILURE);
 6565      }
 6566      --argc;
 6567      if(!sscanf(argv[no_arg-argc],"%lf",&qmper)) {
 6568         fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
 6569         fprintf(stderr,"%s: (Could not read data for qm [3rd arg]).\n",progname);
 6570         exit(FAILURE);
 6571      }
 6572   }
 6573   
 6574   @ Parse the command line for options related to the initiation of a sinusoidal
 6575   grating, consisting of a set of stacked layers.
 6576   
 6577   @<Parse for chirped grating options@>=
 6578   {
 6579      strcpy(gratingtype,argv[no_arg-argc]);
 6580      --argc;
 6581      if(strcmp(argv[no_arg-argc],"n")) {
 6582         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6583         fprintf(stderr,"%s: (Expecting string 'n').\n",progname);
 6584         exit(FAILURE);
 6585      }
 6586      --argc;
 6587      if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
 6588         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6589         fprintf(stderr,"%s: (Could not read data for n [1st arg]).\n",progname);
 6590         exit(FAILURE);
 6591      }
 6592      --argc;
 6593      if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
 6594         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6595         fprintf(stderr,"%s: (Could not read data for n [2nd arg]).\n",progname);
 6596         exit(FAILURE);
 6597      }
 6598      --argc;
 6599      if(!sscanf(argv[no_arg-argc],"%lf",&nper)) {
 6600         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6601         fprintf(stderr,"%s: (Could not read data for n [3rd arg]).\n",progname);
 6602         exit(FAILURE);
 6603      }
 6604      --argc;
 6605      if(!sscanf(argv[no_arg-argc],"%lf",&ncrp)) {
 6606         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6607         fprintf(stderr,"%s: (Could not read data for n [4th arg]).\n",progname);
 6608         exit(FAILURE);
 6609      }
 6610      --argc;
 6611      if(strcmp(argv[no_arg-argc],"g")) {
 6612         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6613         fprintf(stderr,"%s: (Expecting string 'g').\n",progname);
 6614         exit(FAILURE);
 6615      }
 6616      --argc;
 6617      if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
 6618         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6619         fprintf(stderr,"%s: (Could not read data for g [1st arg]).\n",progname);
 6620         exit(FAILURE);
 6621      }
 6622      --argc;
 6623      if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
 6624         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6625         fprintf(stderr,"%s: (Could not read data for g [2nd arg]).\n",progname);
 6626         exit(FAILURE);
 6627      }
 6628      --argc;
 6629      if(!sscanf(argv[no_arg-argc],"%lf",&gper)) {
 6630         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6631         fprintf(stderr,"%s: (Could not read data for g [3rd arg]).\n",progname);
 6632         exit(FAILURE);
 6633      }
 6634      --argc;
 6635      if(!sscanf(argv[no_arg-argc],"%lf",&gcrp)) {
 6636         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6637         fprintf(stderr,"%s: (Could not read data for g [4th arg]).\n",progname);
 6638         exit(FAILURE);
 6639      }
 6640      --argc;
 6641      if(strcmp(argv[no_arg-argc],"pe")) {
 6642         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6643         fprintf(stderr,"%s: (Expecting string 'pe').\n",progname);
 6644         exit(FAILURE);
 6645      }
 6646      --argc;
 6647      if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
 6648         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6649         fprintf(stderr,"%s: (Could not read data for pe [1st arg]).\n",progname);
 6650         exit(FAILURE);
 6651      }
 6652      --argc;
 6653      if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
 6654         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6655         fprintf(stderr,"%s: (Could not read data for pe [2nd arg]).\n",progname);
 6656         exit(FAILURE);
 6657      }
 6658      --argc;
 6659      if(!sscanf(argv[no_arg-argc],"%lf",&peper)) {
 6660         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6661         fprintf(stderr,"%s: (Could not read data for pe [3rd arg]).\n",progname);
 6662         exit(FAILURE);
 6663      }
 6664      --argc;
 6665      if(!sscanf(argv[no_arg-argc],"%lf",&pecrp)) {
 6666         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6667         fprintf(stderr,"%s: (Could not read data for pe [4th arg]).\n",progname);
 6668         exit(FAILURE);
 6669      }
 6670      --argc;
 6671      if(strcmp(argv[no_arg-argc],"pm")) {
 6672         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6673         fprintf(stderr,"%s: (Expecting string 'pm').\n",progname);
 6674         exit(FAILURE);
 6675      }
 6676      --argc;
 6677      if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
 6678         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6679         fprintf(stderr,"%s: (Could not read data for pm [1st arg]).\n",progname);
 6680         exit(FAILURE);
 6681      }
 6682      --argc;
 6683      if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
 6684         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6685         fprintf(stderr,"%s: (Could not read data for pm [2nd arg]).\n",progname);
 6686         exit(FAILURE);
 6687      }
 6688      --argc;
 6689      if(!sscanf(argv[no_arg-argc],"%lf",&pmper)) {
 6690         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6691         fprintf(stderr,"%s: (Could not read data for pm [3rd arg]).\n",progname);
 6692         exit(FAILURE);
 6693      }
 6694      --argc;
 6695      if(!sscanf(argv[no_arg-argc],"%lf",&pmcrp)) {
 6696         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6697         fprintf(stderr,"%s: (Could not read data for pm [4th arg]).\n",progname);
 6698         exit(FAILURE);
 6699      }
 6700      --argc;
 6701      if(strcmp(argv[no_arg-argc],"qe")) {
 6702         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6703         fprintf(stderr,"%s: (Expecting string 'qe').\n",progname);
 6704         exit(FAILURE);
 6705      }
 6706      --argc;
 6707      if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
 6708         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6709         fprintf(stderr,"%s: (Could not read data for qe [1st arg]).\n",progname);
 6710         exit(FAILURE);
 6711      }
 6712      --argc;
 6713      if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
 6714         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6715         fprintf(stderr,"%s: (Could not read data for qe [2nd arg]).\n",progname);
 6716         exit(FAILURE);
 6717      }
 6718      --argc;
 6719      if(!sscanf(argv[no_arg-argc],"%lf",&qeper)) {
 6720         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6721         fprintf(stderr,"%s: (Could not read data for qe [3rd arg]).\n",progname);
 6722         exit(FAILURE);
 6723      }
 6724      --argc;
 6725      if(!sscanf(argv[no_arg-argc],"%lf",&qecrp)) {
 6726         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6727         fprintf(stderr,"%s: (Could not read data for qe [4th arg]).\n",progname);
 6728         exit(FAILURE);
 6729      }
 6730      --argc;
 6731      if(strcmp(argv[no_arg-argc],"qm")) {
 6732         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6733         fprintf(stderr,"%s: (Expecting string 'qm').\n",progname);
 6734         exit(FAILURE);
 6735      }
 6736      --argc;
 6737      if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
 6738         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6739         fprintf(stderr,"%s: (Could not read data for qm [1st arg]).\n",progname);
 6740         exit(FAILURE);
 6741      }
 6742      --argc;
 6743      if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
 6744         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6745         fprintf(stderr,"%s: (Could not read data for qm [2nd arg]).\n",progname);
 6746         exit(FAILURE);
 6747      }
 6748      --argc;
 6749      if(!sscanf(argv[no_arg-argc],"%lf",&qmper)) {
 6750         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6751         fprintf(stderr,"%s: (Could not read data for qm [3rd arg]).\n",progname);
 6752         exit(FAILURE);
 6753      }
 6754      --argc;
 6755      if(!sscanf(argv[no_arg-argc],"%lf",&qmcrp)) {
 6756         fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
 6757         fprintf(stderr,"%s: (Could not read data for qm [4th arg]).\n",progname);
 6758         exit(FAILURE);
 6759      }
 6760   }
 6761   
 6762   @ Parse the command line for options related to the initiation of a fractal
 6763   grating, consisting of a set of stacked homogeneous layers of thicknesses
 6764   corresponding to a Cantor-set fractal.
 6765   
 6766   @<Parse for fractal grating options@>=
 6767   {
 6768      strcpy(gratingtype,argv[no_arg-argc]);
 6769      --argc;
 6770      if(!strcmp(argv[no_arg-argc],"cantor")) {
 6771         strcpy(gratingsubtype,argv[no_arg-argc]);
 6772         --argc;
 6773         if(strcmp(argv[no_arg-argc],"fractal_level")) {
 6774            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6775            fprintf(stderr,"%s: (Expecting string 'fractal_level').\n",progname);
 6776            exit(FAILURE);
 6777         }
 6778         --argc;
 6779         if(!sscanf(argv[no_arg-argc],"%d",&fractal_level)) {
 6780            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6781            fprintf(stderr,"%s: (Could not read data for fractal_level).\n",
 6782               progname);
 6783            exit(FAILURE);
 6784         }
 6785         --argc;
 6786         if(strcmp(argv[no_arg-argc],"maximum_fractal_level")) {
 6787            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6788            fprintf(stderr,"%s: (Expecting string 'maximum_fractal_level').\n",
 6789               progname);
 6790            exit(FAILURE);
 6791         }
 6792         --argc;
 6793         if(!sscanf(argv[no_arg-argc],"%d",&maximum_fractal_level)) {
 6794            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6795            fprintf(stderr,"%s: (Could not read data for maximum_fractal_level).\n",
 6796               progname);
 6797            exit(FAILURE);
 6798         }
 6799         nn=1;
 6800         for (j=1;j<=fractal_level;j++) nn=2*nn;
 6801         --argc;
 6802         if(strcmp(argv[no_arg-argc],"t1")) {
 6803            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6804            fprintf(stderr,"%s: (Expecting string 't1').\n",progname);
 6805            exit(FAILURE);
 6806         }
 6807         --argc;
 6808         if(!sscanf(argv[no_arg-argc],"%lf",&t1)) {
 6809            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6810            fprintf(stderr,"%s: (Could not read data for t1).\n",progname);
 6811            exit(FAILURE);
 6812         }
 6813         --argc;
 6814         if(strcmp(argv[no_arg-argc],"t2")) {
 6815            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6816            fprintf(stderr,"%s: (Expecting string 't2').\n",progname);
 6817            exit(FAILURE);
 6818         }
 6819         --argc;
 6820         if(!sscanf(argv[no_arg-argc],"%lf",&t2)) {
 6821            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6822            fprintf(stderr,"%s: (Could not read data for t2).\n",progname);
 6823            exit(FAILURE);
 6824         }
 6825         --argc;
 6826         if(strcmp(argv[no_arg-argc],"n1")) {
 6827            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6828            fprintf(stderr,"%s: (Expecting string 'n1').\n",progname);
 6829            exit(FAILURE);
 6830         }
 6831         --argc;
 6832         if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
 6833            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6834            fprintf(stderr,"%s: (Could not read data for n1).\n",progname);
 6835            exit(FAILURE);
 6836         }
 6837         --argc;
 6838         if(strcmp(argv[no_arg-argc],"n2")) {
 6839            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6840            fprintf(stderr,"%s: (Expecting string 'n2').\n",progname);
 6841            exit(FAILURE);
 6842         }
 6843         --argc;
 6844         if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
 6845            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6846            fprintf(stderr,"%s: (Could not read data for n2).\n",progname);
 6847            exit(FAILURE);
 6848         }
 6849         --argc;
 6850         if(strcmp(argv[no_arg-argc],"g1")) {
 6851            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6852            fprintf(stderr,"%s: (Expecting string 'g1').\n",progname);
 6853            exit(FAILURE);
 6854         }
 6855         --argc;
 6856         if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
 6857            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6858            fprintf(stderr,"%s: (Could not read data for g1).\n",progname);
 6859            exit(FAILURE);
 6860         }
 6861         --argc;
 6862         if(strcmp(argv[no_arg-argc],"g2")) {
 6863            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6864            fprintf(stderr,"%s: (Expecting string 'g2').\n",progname);
 6865            exit(FAILURE);
 6866         }
 6867         --argc;
 6868         if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
 6869            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6870            fprintf(stderr,"%s: (Could not read data for g2).\n",progname);
 6871            exit(FAILURE);
 6872         }
 6873         --argc;
 6874         if(strcmp(argv[no_arg-argc],"pe1")) {
 6875            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6876            fprintf(stderr,"%s: (Expecting string 'pe1').\n",progname);
 6877            exit(FAILURE);
 6878         }
 6879         --argc;
 6880         if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
 6881            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6882            fprintf(stderr,"%s: (Could not read data for pe1).\n",progname);
 6883            exit(FAILURE);
 6884         }
 6885         --argc;
 6886         if(strcmp(argv[no_arg-argc],"pe2")) {
 6887            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6888            fprintf(stderr,"%s: (Expecting string 'pe2').\n",progname);
 6889            exit(FAILURE);
 6890         }
 6891         --argc;
 6892         if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
 6893            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6894            fprintf(stderr,"%s: (Could not read data for pe2).\n",progname);
 6895            exit(FAILURE);
 6896         }
 6897         --argc;
 6898         if(strcmp(argv[no_arg-argc],"pm1")) {
 6899            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6900            fprintf(stderr,"%s: (Expecting string 'pm1').\n",progname);
 6901            exit(FAILURE);
 6902         }
 6903         --argc;
 6904         if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
 6905            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6906            fprintf(stderr,"%s: (Could not read data for pm1).\n",\
 6907               progname);
 6908            exit(FAILURE);
 6909         }
 6910         --argc;
 6911         if(strcmp(argv[no_arg-argc],"pm2")) {
 6912            fprintf(stderr,"%s: Error.\n",progname);
 6913            fprintf(stderr,"%s: (Expecting string 'pm2').\n",progname);
 6914            exit(FAILURE);
 6915         }
 6916         --argc;
 6917         if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
 6918            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6919            fprintf(stderr,"%s: (Could not read data for pm2).\n",\
 6920               progname);
 6921            exit(FAILURE);
 6922         }
 6923         --argc;
 6924         if(strcmp(argv[no_arg-argc],"qe1")) {
 6925            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6926            fprintf(stderr,"%s: (Expecting string 'qe1').\n",progname);
 6927            exit(FAILURE);
 6928         }
 6929         --argc;
 6930         if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
 6931            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6932            fprintf(stderr,"%s: (Could not read data for qe1).\n",\
 6933               progname);
 6934            exit(FAILURE);
 6935         }
 6936         --argc;
 6937         if(strcmp(argv[no_arg-argc],"qe2")) {
 6938            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6939            fprintf(stderr,"%s: (Expecting string 'qe2').\n",progname);
 6940            exit(FAILURE);
 6941         }
 6942         --argc;
 6943         if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
 6944            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6945            fprintf(stderr,"%s: (Could not read data for qe2).\n",progname);
 6946            exit(FAILURE);
 6947         }
 6948         --argc;
 6949         if(strcmp(argv[no_arg-argc],"qm1")) {
 6950            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6951            fprintf(stderr,"%s: (Expecting string 'qm1').\n",progname);
 6952            exit(FAILURE);
 6953         }
 6954         --argc;
 6955         if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
 6956            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6957            fprintf(stderr,"%s: (Could not read data for qm1).\n",progname);
 6958            exit(FAILURE);
 6959         }
 6960         --argc;
 6961         if(strcmp(argv[no_arg-argc],"qm2")) {
 6962            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6963            fprintf(stderr,"%s: (Expecting string 'qm2').\n",progname);
 6964            exit(FAILURE);
 6965         }
 6966         --argc;
 6967         if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
 6968            fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
 6969            fprintf(stderr,"%s: (Could not read data for qm2).\n",progname);
 6970            exit(FAILURE);
 6971         }
 6972      } else {
 6973         fprintf(stderr,"%s: Error in 'fractal' grating option.\n",progname);
 6974         fprintf(stderr,"%s: (No valid fractal type found!)\n",progname);
 6975         fprintf(stderr,"%s: (Currently only Cantor type implemented)\n",progname);
 6976         exit(FAILURE);
 6977      }
 6978   }
 6979   
 6980   @ Parse the command line for options related to the manual modification of an
 6981   arbitrary discrete layer of the grating structure (which may be of type
 6982   stepwise twolevel, sinusoidal, chirped, or any other, arbitrary type).
 6983   
 6984   @<Parse for options for modified layer of grating structure@>=
 6985   {
 6986      --argc;
 6987      if(strcmp(argv[no_arg-argc],"num")) {
 6988         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 6989         fprintf(stderr,"%s: (Expecting string 'num' after '--modifylayer').\n",
 6990            progname);
 6991         exit(FAILURE);
 6992      }
 6993      --argc;
 6994      if(!sscanf(argv[no_arg-argc],"%ld",&modnum)) {
 6995         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 6996         fprintf(stderr,"%s: (Could not read data for num).\n",progname);
 6997         exit(FAILURE);
 6998      }
 6999      --argc;
 7000      if(strcmp(argv[no_arg-argc],"t")) {
 7001         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7002         fprintf(stderr,"%s: (Expecting string 't' [for layer thickness]).\n",
 7003            progname);
 7004         exit(FAILURE);
 7005      }
 7006      --argc;
 7007      if(!sscanf(argv[no_arg-argc],"%lf",&modt1)) {
 7008         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7009         fprintf(stderr,"%s: (Could not read data for t [layer thickness]).\n",
 7010            progname);
 7011         exit(FAILURE);
 7012      }
 7013      --argc;
 7014      if(strcmp(argv[no_arg-argc],"n")) {
 7015         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7016         fprintf(stderr,"%s: (Expecting string 'n' [for refractive index]).\n",
 7017            progname);
 7018         exit(FAILURE);
 7019      }
 7020      --argc;
 7021      if(!sscanf(argv[no_arg-argc],"%lf",&modn1)) {
 7022         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7023         fprintf(stderr,"%s: (Could not read data for n [refractive index]).\n",
 7024            progname);
 7025         exit(FAILURE);
 7026      }
 7027      --argc;
 7028      if(strcmp(argv[no_arg-argc],"g")) {
 7029         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7030         fprintf(stderr,"%s: (Expecting string 'g' [for gyration constant]).\n",
 7031            progname);
 7032         exit(FAILURE);
 7033      }
 7034      --argc;
 7035      if(!sscanf(argv[no_arg-argc],"%lf",&modg1)) {
 7036         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7037         fprintf(stderr,"%s: (Could not read data for g [gyration constant]).\n",
 7038            progname);
 7039         exit(FAILURE);
 7040      }
 7041      --argc;
 7042      if(strcmp(argv[no_arg-argc],"pe")) {
 7043         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7044         fprintf(stderr,"%s: (Expecting string 'pe').\n",progname);
 7045         exit(FAILURE);
 7046      }
 7047      --argc;
 7048      if(!sscanf(argv[no_arg-argc],"%lf",&modpe1)) {
 7049         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7050         fprintf(stderr,"%s: (Could not read data for pe).\n",progname);
 7051         exit(FAILURE);
 7052      }
 7053      --argc;
 7054      if(strcmp(argv[no_arg-argc],"pm")) {
 7055         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7056         fprintf(stderr,"%s: (Expecting string 'pm').\n",progname);
 7057         exit(FAILURE);
 7058      }
 7059      --argc;
 7060      if(!sscanf(argv[no_arg-argc],"%lf",&modpm1)) {
 7061         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7062         fprintf(stderr,"%s: (Could not read data for pm).\n",progname);
 7063         exit(FAILURE);
 7064      }
 7065      --argc;
 7066      if(strcmp(argv[no_arg-argc],"qe")) {
 7067         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7068         fprintf(stderr,"%s: (Expecting string 'qe').\n",progname);
 7069         exit(FAILURE);
 7070      }
 7071      --argc;
 7072      if(!sscanf(argv[no_arg-argc],"%lf",&modqe1)) {
 7073         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7074         fprintf(stderr,"%s: (Could not read data for qe).\n",progname);
 7075         exit(FAILURE);
 7076      }
 7077      --argc;
 7078      if(strcmp(argv[no_arg-argc],"qm")) {
 7079         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7080         fprintf(stderr,"%s: (Expecting string 'qm').\n",progname);
 7081         exit(FAILURE);
 7082      }
 7083      --argc;
 7084      if(!sscanf(argv[no_arg-argc],"%lf",&modqm1)) {
 7085         fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
 7086         fprintf(stderr,"%s: (Could not read data for qm).\n",progname);
 7087         exit(FAILURE);
 7088      }
 7089   }
 7090   
 7091   @ Parse the command line for options specifying the transmitted optical
 7092   intensity range.
 7093   The command line syntax for specification of the transmitted optical intensity
 7094   range is
 7095   \smallskip
 7096   \centerline{\hbox to 40pt{}\.{--trmintensity}
 7097     $\langle I_{\rm start}\rangle$ $\langle I_{\rm stop}\rangle$
 7098     $\langle M_{\rm i}\rangle$\hfill}
 7099   \smallskip\noindent
 7100   where the numerical values supplied are internally kept by the variables
 7101   |trmintenstart|, |trmintenstop|, and |mmi|, respectively.
 7102   
 7103   @<Parse the command line for transmitted intensity range@>=
 7104   {
 7105      --argc;
 7106      if(!sscanf(argv[no_arg-argc],"%lf",&trmintenstart)) {
 7107         fprintf(stderr,"%s: Error in '--trmintensity' option.\n",\
 7108            progname);
 7109         exit(FAILURE);
 7110      }
 7111      --argc;
 7112      if(!sscanf(argv[no_arg-argc],"%lf",&trmintenstop)) {
 7113         fprintf(stderr,"%s: Error in '--trmintensity' option.\n",\
 7114            progname);
 7115         exit(FAILURE);
 7116      }
 7117      --argc;
 7118      if(!sscanf(argv[no_arg-argc],"%ld",&mmi)) {
 7119         fprintf(stderr,"%s: Error in '--trmintensity' option.\n",\
 7120            progname);
 7121         exit(FAILURE);
 7122      }
 7123   }
 7124   
 7125   @ Parse the command line for options specifying the ellipticity range of the
 7126   transmitted polarization state. The command line syntax for specification of
 7127   the ellipticity of the transmitted polarization state is analogous to that
 7128   of the transmitted intensity,
 7129   \smallskip
 7130   \centerline{\hbox to 40pt{}\.{--trmellipticity}
 7131     $\langle \epsilon_{\rm start}\rangle$ $\langle \epsilon_{\rm stop}\rangle$
 7132     $\langle M_{\rm e}\rangle$\hfill}
 7133   \smallskip\noindent
 7134   where the numerical values supplied are internally kept by the variables
 7135   |trmellipstart|, |trmellipstop|, and |mme|, respectively.
 7136   
 7137   @<Parse the command line for transmitted ellipticity range@>=
 7138   {
 7139      --argc;
 7140      if(!sscanf(argv[no_arg-argc],"%lf",&trmellipstart)) {
 7141         fprintf(stderr,"%s: Error in '--trmellipticity' option.\n",progname);
 7142         exit(FAILURE);
 7143      }
 7144      --argc;
 7145      if(!sscanf(argv[no_arg-argc],"%lf",&trmellipstop)) {
 7146         fprintf(stderr,"%s: Error in '--trmellipticity' option.\n",progname);
 7147         exit(FAILURE);
 7148      }
 7149      --argc;
 7150      if(!sscanf(argv[no_arg-argc],"%ld",&mme)) {
 7151         fprintf(stderr,"%s: Error in '--trmellipticity' option.\n",progname);
 7152         exit(FAILURE);
 7153      }
 7154   }
 7155   
 7156   @ If the flag |verbose| is set to true (|1| in C), then display the information
 7157   parsed from the command line, such as output filenames, indices of refraction,
 7158   grating period, etc. This is useful for later on creating log files of
 7159   sessions with the executable program \magbragg.
 7160   
 7161   @<Display parameters parsed from the command line@>=
 7162   {
 7163      if (verbose) {
 7164         for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
 7165         fprintf(stdout,"Input parameters:\n");
 7166         fprintf(stdout,
 7167            "Grating type: %s\n",gratingtype);
 7168         if (!strcmp(gratingtype,"sinusoidal")) {
 7169            fprintf(stdout,
 7170               "Bias refractive index:          %10.6e\n",n1);
 7171            fprintf(stdout,
 7172               "Refractive index modulation:    %10.6e\n",n2);
 7173            fprintf(stdout,
 7174               "Modulation period:              %10.6e [m]\n",nper);
 7175         } else if (!strcmp(gratingtype,"chirped")) {
 7176         } else if (!strcmp(gratingtype,"stepwise")) {
 7177         } else if (!strcmp(gratingtype,"fractal")) {
 7178         } else {
 7179            fprintf(stdout,"%s: Error: Unknown grating type '%s'\n",
 7180               progname,gratingtype);
 7181         }
 7182         fprintf(stdout,"Geometrical length:            "
 7183                        "L=%10.6e [m]\n",ll);
 7184         fprintf(stdout,"Surrounding refractive index:  "
 7185                        "nsurr=%10.6e\n",nsurr);
 7186         fprintf(stdout,"Begin wavelength of spectrum:  "
 7187                        "lambda_start=%10.6e [m]\n",lambdastart);
 7188         fprintf(stdout,"End wavelength of spectrum:    "
 7189                        "lambda_stop=%10.6e [m]\n",lambdastop);
 7190         fprintf(stdout,"Number of samples in spectrum: "
 7191                        "M=%-12ld\n",mm);
 7192         fprintf(stdout,"Number of discrete layers:     "
 7193                        "N=%-12ld\n",nn);
 7194         if (trmtraject_specified) {
 7195            fprintf(stdout,"Trajectory for transmitted Stokes parameters: %s\n",
 7196            trmtraject_filename);
 7197         } else {
 7198            fprintf(stdout,"Number of samples in output intensity:   "
 7199                           "mmi=%-12ld\n",mmi);
 7200            fprintf(stdout,"Number of samples in output ellipticity: "
 7201                           "mme=%-12ld\n",mme);
 7202         }
 7203         fprintf(stdout,"Stokes parameters will be written to files:\n");
 7204         fprintf(stdout,"   %s  [S0 (incident wave)],\n",outfilename_s0);
 7205         fprintf(stdout,"   %s  [S1 (incident wave)],\n",outfilename_s1);
 7206         fprintf(stdout,"   %s  [S2 (incident wave)],\n",outfilename_s2);
 7207         fprintf(stdout,"   %s  [S3 (incident wave)],\n",outfilename_s3);
 7208         fprintf(stdout,"   %s  [V0 (reflected wave)],\n",outfilename_v0);
 7209         fprintf(stdout,"   %s  [V1 (reflected wave)],\n",outfilename_v1);
 7210         fprintf(stdout,"   %s  [V2 (reflected wave)],\n",outfilename_v2);
 7211         fprintf(stdout,"   %s  [V3 (reflected wave)],\n",outfilename_v3);
 7212         fprintf(stdout,"   %s  [W0 (transmitted wave)],\n",outfilename_w0);
 7213         fprintf(stdout,"   %s  [W1 (transmitted wave)],\n",outfilename_w1);
 7214         fprintf(stdout,"   %s  [W2 (transmitted wave)],\n",outfilename_w2);
 7215         fprintf(stdout,"   %s  [W3 (transmitted wave)],\n",outfilename_w3);
 7216         if (fieldevoflag) {
 7217            if (fieldevoflag_efield) {
 7218               if(strcmp(fieldevofilename,"")) {
 7219                  fprintf(stdout,"Intra grating optical field evolution will "
 7220                                 "be written to file:\n");
 7221                  fprintf(stdout,"   %s\n",fieldevofilename);
 7222               } else {
 7223                  fprintf(stderr,
 7224                     "%s: Error: No file name specified for saving spatial\n"
 7225                     "field evolution. (efield option)\n",progname);
 7226                  exit(FAILURE);
 7227               }
 7228               fprintf(stdout,
 7229                  "(Intra grating field evolution will be presented in terms of\n"
 7230                  "the electrical field displacement.)\n");
 7231            } else if (fieldevoflag_stoke) {
 7232               if(strcmp(fieldevofilename_s0,"")
 7233                    &&strcmp(fieldevofilename_s1,"")
 7234                    &&strcmp(fieldevofilename_s2,"")
 7235                    &&strcmp(fieldevofilename_s3,"")) {
 7236                  fprintf(stdout,"Intra grating optical field evolution will "
 7237                                 "be written to files:\n");
 7238                  fprintf(stdout,"   %s\n   %s\n   %s\n   %s\n",
 7239                     fieldevofilename_s0,fieldevofilename_s1,
 7240                     fieldevofilename_s2,fieldevofilename_s3);
 7241               } else {
 7242                  fprintf(stderr,
 7243                     "%s: Error: No file name specified for saving spatial\n"
 7244                     "field evolution. (stoke option)\n",progname);
 7245                  exit(FAILURE);
 7246               }
 7247               fprintf(stdout,
 7248                  "(Intra grating field evolution will be presented in terms of\n"
 7249                  "the Stokes parameters of the forward propagating field.)\n");
 7250            } else {
 7251               fprintf(stderr,"%s: Unknown field evolution flag.\n",progname);
 7252               exit(FAILURE);
 7253            }
 7254            fprintf(stdout,
 7255               "Number of intermediate samples within each layer: %-12ld\n",nne);
 7256         }
 7257         if (intensityevoflag) {
 7258            if(strcmp(intensityevofilename,"")) {
 7259               fprintf(stdout,"Intra grating optical intensity evolution will "
 7260                              "be written to file:\n");
 7261               fprintf(stdout,"   %s\n",intensityevofilename);
 7262            }
 7263         }
 7264         fprintf(stdout,"Program execution started %s",ctime(&initime));
 7265         for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
 7266      }
 7267   }
 7268   
 7269   @ Routines for displaying help message to standard terminal output.
 7270   
 7271   @<Routines for displaying help message@>=
 7272      @<Display split help line@>@;
 7273      @<Display full help line@>@;
 7274      @<Display help message@>@;
 7275   
 7276   @ Routine for proper display of split help lines. This is a very simple
 7277   routine just to keep the |fprintf(stderr,"...","...")| statements to a
 7278   minimum. The routine also checks that the full length of the diplayed
 7279   line does not exceed 80 characters, as conforming to normal line length
 7280   of terminal output.
 7281   
 7282   @<Display split help line@>=
 7283   void hl(char firststring[],char secondstring[]) {
 7284      if (strlen(firststring)>25) {
 7285         fprintf(stderr,"%s:******* Error in hl() routine! *******\n",progname);
 7286         fprintf(stderr,"%s: The first string argument is too long:\n",progname);
 7287         fprintf(stderr,"%s:   '%s'\n",progname,firststring);
 7288         fprintf(stderr,"%s: String lengths is %d characters\n",
 7289            progname,(int)strlen(firststring));
 7290         fprintf(stderr,"%s: (Maximum 25 characters for first argument.)\n",
 7291            progname);
 7292         fprintf(stderr,"%s:******** End of error message *********\n",progname);
 7293         exit(FAILURE);
 7294      }
 7295      if (strlen(secondstring)>55) {
 7296         fprintf(stderr,"%s:******* Error in hl() routine! *******\n",progname);
 7297         fprintf(stderr,"%s: The second string argument is too long:\n",progname);
 7298         fprintf(stderr,"%s:   '%s'\n",progname,secondstring);
 7299         fprintf(stderr,"%s: String lengths is %d characters\n",
 7300            progname,(int)strlen(secondstring));
 7301         fprintf(stderr,"%s: (Maximum 55 characters for second argument.)\n",
 7302            progname);
 7303         fprintf(stderr,"%s:******** End of error message *********\n",progname);
 7304         exit(FAILURE);
 7305      }
 7306      fprintf(stderr,"%-25.25s%1.55s\n",firststring,secondstring);
 7307   }
 7308   
 7309   @ Routine for proper display of full help lines. This is similar to the |hl()|
 7310   routine, with the only difference being that a full line of text is flushed
 7311   instead of a line split into two parts.
 7312   
 7313   @<Display full help line@>=
 7314   void fhl(char linestring[]) {
 7315      if (strlen(linestring)>80) {
 7316         fprintf(stderr,"%s:******* Error in fhl() routine! *******\n",progname);
 7317         fprintf(stderr,"%s: The following help line is too long:\n",progname);
 7318         fprintf(stderr,"%s:   '%s'\n",progname,linestring);
 7319         fprintf(stderr,"%s: String is %d characters\n",
 7320            progname,(int)strlen(linestring));
 7321         fprintf(stderr,"%s: (Maximum 80 characters per help line is allowed.)\n",
 7322            progname);
 7323         fprintf(stderr,"%s:******** End of error message *********\n",progname);
 7324         exit(FAILURE);
 7325      }
 7326      fprintf(stderr,"%s\n",linestring);
 7327   }
 7328   
 7329   @ Show a help message at the screen, giving the full syntax of the
 7330   command line options that are accepted by the program.
 7331   
 7332   @<Display help message@>=
 7333   void showsomehelp(void) {
 7334      fprintf(stderr," Usage: %s [options]\n",progname);
 7335      fhl(" Options:");
 7336      hl("  -h, --help","Display this help message and exit clean.");
 7337      hl("  -N <int>","");
 7338      hl("  -M <int>","");
 7339      hl("  -v, --verbose","");
 7340      hl("  -o, --outputfile <str>","");
 7341      fhl("  --fieldevolution {efield|stoke} <n> <str>");
 7342      fhl("  --intensityevolution <lambda> <str>");
 7343      fhl("  --normalize_length_to_um");
 7344      hl("  --normalize_intensity","");
 7345      hl("","When saving the spatial evolution of the intra-");
 7346      hl("","grating intensity, normalize the intensity with");
 7347      hl("","respect to the intensity at z=0, inside the");
 7348      hl("","grating (that is to say, normalize with respect");
 7349      hl("","to the initial intra-grating intensity). This");
 7350      hl("","option *only* affects the fields saved with the");
 7351      hl("","--intensityevolution or --fieldevolution");
 7352      hl("","options.");
 7353      hl("  -r, --random","");
 7354      hl("  -a, --apodize <real>","");
 7355      hl("","Apodize the grating structure over geometrical");
 7356      hl("","distance <real> at each end of the grating.");
 7357      hl("","The option only applies to gratings with sinus-");
 7358      hl("","oidal modulation of refractive index and");
 7359      hl("","gyration coefficient, in constant or chirped");
 7360      hl("","periodic configurations, as specified with the");
 7361      hl("","'--grating sinusoidal' or '--grating chirped'");
 7362      hl("","options respectively.");
 7363      hl("","   The apodization is applied to the refractive");
 7364      hl("","index modulation and, in cases where the linear");
 7365      hl("","magneto-optical is spatially modulated as well,");
 7366      hl("","to the linear gyration coefficient.");
 7367      fhl("  -j, --phasejump <r1 (angle)> <r2 (position)>");
 7368      hl("","Apply discrete phase jump in the spatial phase");
 7369      hl("","of the grating profile. This option adds the");
 7370      hl("","real number <r1> to the argument of the sinus-");
 7371      hl("","oidal function for the grating profile for all");
 7372      hl("","spatial coordinates z >= <r2>.");
 7373      hl("","   As in the case of apodization, this option");
 7374      hl("","only applies to gratings with sinusoidal modu-");
 7375      hl("","lation of refractive index and gyration coeffi-");
 7376      hl("","cient, in constant or chirped periodic configu-");
 7377      hl("","rations, as specified with the '--grating");
 7378      hl("","sinusoidal' or '--grating chirped' options");
 7379      hl("","respectively. The discrete phase jump applies");
 7380      hl("","to the linear linear refractive index modula-");
 7381      hl("","tion and, in cases where the linear magneto-");
 7382      hl("","optical interaction is spatially modulated as");
 7383      hl("","well, also to the linear gyration coefficient.");
 7384      fhl("  -w, --writegratingfile <str>");
 7385      hl("  --spectrumfile <str>","");
 7386      hl("","Generates the complex reflectance as function");
 7387      hl("","of the vacuum wavelength in meters, and save");
 7388      hl("","the spectrum in file named according to the");
 7389      hl("","supplied character string <str>.");
 7390      fhl("  --intensityspectrumfile <str>");
 7391      hl("","Generates the intensity reflectance as function");
 7392      hl("","of the vacuum wavelength in meters, and save");
 7393      hl("","the spectrum in file named according to the");
 7394      hl("","supplied character string <str>.");
 7395      fhl("  -g, --grating <grating options>");
 7396      hl("","Specifies the grating type, where");
 7397      hl("","<grating options> = ");
 7398      hl("","   [stepwise <stepwise options> |");
 7399      hl("","    sinusoidal <sinusoidal options> |");
 7400      hl("","    chirped <chirped options>]");
 7401      hl("","<stepwise options> = ");
 7402      hl("","   twolevel t1  <f> t2 <f>");
 7403      hl("","            n1  <f> n2 <f>  g1  <f> g2  <f>");
 7404      hl("","            pe1 <f> pe2 <f> pm1 <f> pm2 <f>");
 7405      hl("","            qe1 <f> qe2 <f> qm1 <f> qm2 <f>");
 7406      hl("","<sinusoidal options> = ");
 7407      hl("","            n  <n0>  <dn>  <nper>");
 7408      hl("","            g  <g0>  <dg>  <gper>");
 7409      hl("","            pe <pe0> <dpe> <peper>");
 7410      hl("","            pm <pm0> <dpm> <pmper>");
 7411      hl("","            qe <qe0> <dqe> <qeper>");
 7412      hl("","            qm <qm0> <dqm> <qmper>");
 7413      hl("","<chirped options> = ");
 7414      hl("","            n  <n0>  <dn>  <nper>  <ncrp>");
 7415      hl("","            g  <g0>  <dg>  <gper>  <gcrp>");
 7416      hl("","            pe <pe0> <dpe> <peper> <pecrp>");
 7417      hl("","            pm <pm0> <dpm> <pmper> <pmcrp>");
 7418      hl("","            qe <qe0> <dqe> <qeper> <qecrp>");
 7419      hl("","            qm <qm0> <dqm> <qmper> <qmcrp>");
 7420      hl("  -L,--gratinglength <f>","Physical length of grating in meter [m]");
 7421      fhl("     --refindsurr <f>");
 7422      fhl("     --trmtraject <str>");
 7423      fhl("     --trmintensity <istart> <istop> <mmi>");
 7424      fhl("   (intensity measured in Watts per square meter)");
 7425      fhl("     --trmellipticity <estart> <estop> <mme>");
 7426      fhl("     --lambdastart <lambda>");
 7427      fhl("   (start vacuum wavelength measured in meter)");
 7428      fhl("     --lambdastop <lambda>");
 7429      fhl("   (stop vacuum wavelength measured in meter)");
 7430      exit(FAILURE);
 7431   }
 7432   
 7433   @*Check for specified trajectory of transmitted Stokes parameters.
 7434   
 7435   @<Check for specified trajectory of transmitted Stokes parameters@>=
 7436   {
 7437      mmtraject=0;
 7438      if (trmtraject_specified) { /* Was a trajectory specified at all? */
 7439         if ((fp_traject=fopen(trmtraject_filename,"r"))==NULL) {
 7440            fprintf(stderr,
 7441               "%s: Could not open file %s for reading Stokes parameter"
 7442               " trajectory of transmitted wave!\n",
 7443               progname,trmtraject_filename);
 7444            exit(FAILURE);
 7445         }
 7446         fseek(fp_traject,0L,SEEK_SET);
 7447   
 7448         /* Scan the specified file for the number of points of the trajectory */
 7449         while((tmpch=getc(fp_traject))!=EOF) {
 7450            ungetc(tmpch,fp_traject);
 7451            fscanf(fp_traject,"%lf",&tmp); /* Read away the $W_0$ parameter */
 7452            fscanf(fp_traject,"%lf",&tmp); /* Read away the $W_3$ parameter */
 7453            mmtraject++;
 7454   
 7455            /* Read away blanks and linefeeds */
 7456            tmpch=getc(fp_traject);
 7457            while ((tmpch!=EOF)&&(!numeric(tmpch))) {
 7458               tmpch=getc(fp_traject);
 7459            }
 7460            if (tmpch!=EOF) ungetc(tmpch,fp_traject);
 7461         }
 7462   
 7463         if (verbose) {
 7464            fprintf(stdout,
 7465             "%s: I have now pre-parsed the specified trajectory of transmitted\n"
 7466             "Stokes parameters (W0,W3) in file %s, and I found %-ld points.\n",
 7467             progname,trmtraject_filename,mmtraject);
 7468            fprintf(stdout,
 7469             "%s: Now allocating the vectors for the transmitted trajectory...",
 7470             progname);
 7471         }
 7472   
 7473         fseek(fp_traject,0L,SEEK_SET); /* Rewind the file for reading */
 7474         w0traj=dvector(1,mmtraject); /* Allocate memory for |w0traj| */
 7475         w3traj=dvector(1,mmtraject); /* Allocate memory for |w3traj| */
 7476         for (ke=1;ke<=mmtraject;ke++) {
 7477            fscanf(fp_traject,"%le",&w0traj[ke]); /* Read the $W_0$ parameter */
 7478            fscanf(fp_traject,"%le",&w3traj[ke]); /* Read the $W_3$ parameter */
 7479         }
 7480   
 7481   if(0==1) {
 7482         for (ke=1;ke<=mmtraject;ke++)
 7483            fprintf(stdout,"w0=%e   w3=%e\n",w0traj[ke],w3traj[ke]);
 7484   }
 7485   
 7486         fclose(fp_traject);
 7487      }
 7488   }
 7489   
 7490   @*Opening and closing files for data output.
 7491   Open output files, to be used later on for saving Stokes parameters on disk.
 7492   The naming convention of the files is that the |outfilename| string (at the
 7493   command line specified using the \.{-o} $\langle|outfilename|\rangle$
 7494   or \.{--outputfile} $\langle|outfilename|\rangle$ option) is the base
 7495   name, with suffixes \.{.s0.dat}, \.{.s1.dat}, etc., indicating the
 7496   actual Stoke parameter which was written to respective file.
 7497   
 7498   The following string variables contain the filenames of the files where to
 7499   store the calculated data:
 7500   \varitem[{$|outfilename_s0|$}]{The $S_0$ Stokes parameter of the incident
 7501      optical wave, governing the optical intensity.}
 7502   \varitem[{$|outfilename_s1|$}]{The $S_1$ Stokes parameter of the incident
 7503      optical wave, together with $S_2$ governing the orientation of the main
 7504      axis of the polarization ellipse.}
 7505   \varitem[{$|outfilename_s2|$}]{The $S_2$ Stokes parameter of the incident
 7506      optical wave, together with $S_1$ governing the orientation of the main
 7507      axis of the polarization ellipse.}
 7508   \varitem[{$|outfilename_s3|$}]{The $S_3$ Stokes parameter of the incident
 7509      optical wave, governing the polarization state ellipticity.}
 7510   \varitem[{$|outfilename_v0|$}]{The $V_0$ Stokes parameter of the reflected
 7511      optical wave, governing the optical intensity.}
 7512   \varitem[{$|outfilename_v1|$}]{The $V_1$ Stokes parameter of the reflected
 7513      optical wave, together with $V_2$ governing the orientation of the main
 7514      axis of the polarization ellipse.}
 7515   \varitem[{$|outfilename_v2|$}]{The $V_2$ Stokes parameter of the reflected
 7516      optical wave, together with $V_1$ governing the orientation of the main
 7517      axis of the polarization ellipse.}
 7518   \varitem[{$|outfilename_v3|$}]{The $V_3$ Stokes parameter of the reflected
 7519      optical wave, governing the polarization state ellipticity.}
 7520   \varitem[{$|outfilename_w0|$}]{The $W_0$ Stokes parameter of the transmitted
 7521      optical wave, governing the optical intensity.}
 7522   \varitem[{$|outfilename_w1|$}]{The $W_1$ Stokes parameter of the transmitted
 7523      optical wave, together with $W_2$ governing the orientation of the main
 7524      axis of the polarization ellipse.}
 7525   \varitem[{$|outfilename_w2|$}]{The $W_2$ Stokes parameter of the transmitted
 7526      optical wave, together with $W_1$ governing the orientation of the main
 7527      axis of the polarization ellipse.}
 7528   \varitem[{$|outfilename_w3|$}]{The $W_3$ Stokes parameter of the transmitted
 7529      optical wave, governing the polarization state ellipticity.}
 7530   \medskip
 7531   \noindent
 7532   The reason for using separate files for the Stokes parameters is that
 7533   in many cases sets or matrices of Stokes parameters will be generated
 7534   for certain material or geometrical parameters, resulting in several different
 7535   topological
 7536   surfaces of, for example, transmitted intensity $W_0$ as function of
 7537   input intensity $S_0$ and ellipticity $S_3/S_0$, in which case it is
 7538   convenient to load separate Stokes parameters from separate files.
 7539   
 7540   @<Open files for output@>=
 7541   {
 7542      if ((mme>1)&&(mmi>1)) {
 7543         if ((fp_s0=fopen(outfilename_s0,"w"))==NULL) {
 7544            fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
 7545               progname,outfilename_s0);
 7546            exit(FAILURE);
 7547         }
 7548         if ((fp_s1=fopen(outfilename_s1,"w"))==NULL) {
 7549            fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
 7550               progname,outfilename_s1);
 7551            exit(FAILURE);
 7552         }
 7553         if ((fp_s2=fopen(outfilename_s2,"w"))==NULL) {
 7554            fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
 7555               progname,outfilename_s2);
 7556            exit(FAILURE);
 7557         }
 7558         if ((fp_s3=fopen(outfilename_s3,"w"))==NULL) {
 7559            fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
 7560               progname,outfilename_s3);
 7561            exit(FAILURE);
 7562         }
 7563         if ((fp_v0=fopen(outfilename_v0,"w"))==NULL) {
 7564            fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
 7565               progname,outfilename_v0);
 7566            exit(FAILURE);
 7567         }
 7568         if ((fp_v1=fopen(outfilename_v1,"w"))==NULL) {
 7569            fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
 7570               progname,outfilename_v1);
 7571            exit(FAILURE);
 7572         }
 7573         if ((fp_v2=fopen(outfilename_v2,"w"))==NULL) {
 7574            fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
 7575               progname,outfilename_v2);
 7576            exit(FAILURE);
 7577         }
 7578         if ((fp_v3=fopen(outfilename_v3,"w"))==NULL) {
 7579            fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
 7580               progname,outfilename_v3);
 7581            exit(FAILURE);
 7582         }
 7583         if ((fp_w0=fopen(outfilename_w0,"w"))==NULL) {
 7584            fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
 7585               progname,outfilename_w0);
 7586            exit(FAILURE);
 7587         }
 7588         if ((fp_w1=fopen(outfilename_w1,"w"))==NULL) {
 7589            fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
 7590               progname,outfilename_w1);
 7591            exit(FAILURE);
 7592         }
 7593         if ((fp_w2=fopen(outfilename_w2,"w"))==NULL) {
 7594            fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
 7595               progname,outfilename_w2);
 7596            exit(FAILURE);
 7597         }
 7598         if ((fp_w3=fopen(outfilename_w3,"w"))==NULL) {
 7599            fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
 7600               progname,outfilename_w3);
 7601            exit(FAILURE);
 7602         }
 7603      }
 7604      if ((mme>1)&&(mmi>1)) {
 7605         fseek(fp_s0,0L,SEEK_SET);
 7606         fseek(fp_s1,0L,SEEK_SET);
 7607         fseek(fp_s2,0L,SEEK_SET);
 7608         fseek(fp_s3,0L,SEEK_SET);
 7609         fseek(fp_v0,0L,SEEK_SET);
 7610         fseek(fp_v1,0L,SEEK_SET);
 7611         fseek(fp_v2,0L,SEEK_SET);
 7612         fseek(fp_v3,0L,SEEK_SET);
 7613         fseek(fp_w0,0L,SEEK_SET);
 7614         fseek(fp_w1,0L,SEEK_SET);
 7615         fseek(fp_w2,0L,SEEK_SET);
 7616         fseek(fp_w3,0L,SEEK_SET);
 7617      }
 7618      if (fieldevoflag) {
 7619         if (fieldevoflag_efield) {
 7620            if(strcmp(fieldevofilename,"")) {
 7621               if ((fp_evo=fopen(fieldevofilename,"w"))==NULL) {
 7622                  fprintf(stderr,
 7623                     "%s: Could not open file %s for fieldevo output!\n",
 7624                     progname,fieldevofilename);
 7625                  exit(FAILURE);
 7626               }
 7627            }
 7628         } else if (fieldevoflag_stoke) {
 7629            if(strcmp(fieldevofilename_s0,"")) {
 7630               if ((fp_evo_s0=fopen(fieldevofilename_s0,"w"))==NULL) {
 7631                  fprintf(stderr,
 7632                     "%s: Could not open file %s for saving spatial S0"
 7633                     " distribution!\n",progname,fieldevofilename);
 7634                  exit(FAILURE);
 7635               }
 7636            } else {
 7637               fprintf(stderr,
 7638                  "%s: A name for the file for saving spatial S0 distribution"
 7639                  " is required!\n",progname);
 7640               exit(FAILURE);
 7641            }
 7642            if(strcmp(fieldevofilename_s1,"")) {
 7643               if ((fp_evo_s1=fopen(fieldevofilename_s1,"w"))==NULL) {
 7644                  fprintf(stderr,
 7645                     "%s: Could not open file %s for saving spatial S1"
 7646                     " distribution!\n",progname,fieldevofilename);
 7647                  exit(FAILURE);
 7648               }
 7649            } else {
 7650               fprintf(stderr,
 7651                  "%s: A name for the file for saving spatial S1 distribution"
 7652                  " is required!\n",progname);
 7653               exit(FAILURE);
 7654            }
 7655            if(strcmp(fieldevofilename_s2,"")) {
 7656               if ((fp_evo_s2=fopen(fieldevofilename_s2,"w"))==NULL) {
 7657                  fprintf(stderr,
 7658                     "%s: Could not open file %s for saving spatial S2"
 7659                     " distribution!\n",progname,fieldevofilename);
 7660                  exit(FAILURE);
 7661               }
 7662            } else {
 7663               fprintf(stderr,
 7664                  "%s: A name for the file for saving spatial S2 distribution"
 7665                  " is required!\n",progname);
 7666               exit(FAILURE);
 7667            }
 7668            if(strcmp(fieldevofilename_s3,"")) {
 7669               if ((fp_evo_s3=fopen(fieldevofilename_s3,"w"))==NULL) {
 7670                  fprintf(stderr,
 7671                     "%s: Could not open file %s for saving spatial S3"
 7672                     " distribution!\n",progname,fieldevofilename);
 7673                  exit(FAILURE);
 7674               }
 7675            } else {
 7676               fprintf(stderr,
 7677                  "%s: A name for the file for saving spatial S3 distribution"
 7678                  " is required!\n",progname);
 7679               exit(FAILURE);
 7680            }
 7681         } else {
 7682            fprintf(stderr,"%s: Unknown field evolution flag.\n",progname);
 7683            exit(FAILURE);
 7684         }
 7685      }
 7686      if (intensityevoflag) {
 7687         if(strcmp(intensityevofilename,"")) {
 7688            if ((fp_ievo=fopen(intensityevofilename,"w"))==NULL) {
 7689               fprintf(stderr,
 7690                  "%s: Could not open file %s for intensityevo output!\n",
 7691                  progname,intensityevofilename);
 7692               exit(FAILURE);
 7693            }
 7694         }
 7695      }
 7696      if (!((mme>1)&&(mmi>1))) {
 7697         if ((fp_spec=fopen(spectrumfilename,"w"))==NULL) {
 7698            fprintf(stderr,"%s: Could not open file %s for spectrum output!\n",
 7699               progname,spectrumfilename);
 7700            exit(FAILURE);
 7701         }
 7702         if ((fp_irspec=fopen(intensity_reflection_spectrumfilename,"w"))==NULL) {
 7703            fprintf(stderr,
 7704               "%s: Could not open %s for intensity reflection spectrum!\n",
 7705               progname,intensity_reflection_spectrumfilename);
 7706            exit(FAILURE);
 7707         }
 7708         if ((fp_itspec=fopen(intensity_transmission_spectrumfilename,"w"))==NULL) {
 7709            fprintf(stderr,
 7710               "%s: Could not open %s for intensity transmission spectrum!\n",
 7711               progname,intensity_transmission_spectrumfilename);
 7712            exit(FAILURE);
 7713         }
 7714         if ((fp_icspec=fopen(intensity_check_spectrumfilename,"w"))==NULL) {
 7715            fprintf(stderr,
 7716               "%s: Could not open %s for checking spectra!\n",
 7717               progname,intensity_check_spectrumfilename);
 7718            exit(FAILURE);
 7719         }
 7720      }
 7721   }
 7722   
 7723   @ Close all open files.
 7724   
 7725   @<Close output files@>=
 7726   {
 7727      if ((mme>1)&&(mmi>1)) {
 7728         fclose(fp_s0);
 7729         fclose(fp_s1);
 7730         fclose(fp_s2);
 7731         fclose(fp_s3);
 7732         fclose(fp_v0);
 7733         fclose(fp_v1);
 7734         fclose(fp_v2);
 7735         fclose(fp_v3);
 7736         fclose(fp_w0);
 7737         fclose(fp_w1);
 7738         fclose(fp_w2);
 7739         fclose(fp_w3);
 7740      }
 7741      if (fieldevoflag) if(strcmp(fieldevofilename,"")) fclose(fp_evo);
 7742      if (intensityevoflag) if(strcmp(intensityevofilename,"")) fclose(fp_ievo);
 7743      if (!((mme>1)&&(mmi>1))) {
 7744         fclose(fp_spec);
 7745         fclose(fp_irspec);
 7746         fclose(fp_itspec);
 7747         fclose(fp_icspec);
 7748      }
 7749   }
 7750   
 7751   @*References.
 7752   
 7753   \refitem[1]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Polarization
 7754   State Controlled Multistability of a Nonlinear Magneto-optic Cavity},
 7755   Phys. Rev. Lett. {\bf 82}, 1426 (1999).}
 7756   
 7757   \refitem[2]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Nonlinear Magneto-Optical
 7758   Bragg Gratings}, Phys. Rev. Lett. {\bf 96}, 063902 (2006).}
 7759   
 7760   \refitem[3]{Y.\thinspace{R.}~Shen, {\sl The Principles of Nonlinear Optics}
 7761   (Wiley, New York, 1984), {ISBN\thinspace0-471-88998-9}.
 7762   
 7763   \refitem[4]{A.\thinspace{K.}~Zvezdin and V.\thinspace{A.}~Kotov, {\sl Modern
 7764   Magnetooptics and Magnetooptical Materials}, (In\-sti\-tute of Phy\-sics
 7765   Pub\-lish\-ing, London, 1997), {ISBN\thinspace0-7503-0362-X}.}
 7766   
 7767   \refitem[5]{{J.\thinspace{D.}~Jackson},
 7768   {\sl Classical Electrodynamics}, 2nd Ed.~(Wiley, New York, 1975)
 7769   {ISBN\thinspace0-471-43132-X}.}
 7770   
 7771   \refitem[6]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Optical amplitude and phase
 7772   evolution in nonlinear magneto-optical Bragg gratings}, J.~Nonlin.~Opt.
 7773   Physics and Materials {\bf 13}, 129 (2004).}
 7774   
 7775   \refitem[7]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Spectral windowing with
 7776   chirped magneto-optical Bragg gratings}, {J.~Opt. Soc. Am. B} {\bf 22}, 293
 7777   (2005).}
 7778   
 7779   \refitem[8]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Artificially Induced
 7780   Perturbations in Chirped Magneto-Optical {Bragg} Gratings}, in
 7781   {\sl Magneto-Optical Materials for Photonics and Recording}, Eds.~{Koji Ando,
 7782   W. Challener, R. Gambino and M. Levy}, Mater. Res. Soc. Symp. Proc. {\bf 834},
 7783   J1.8 ({Materials Research Society}, {Warrendale}, 2005).}
 7784   
 7785   \refitem[9]{{F.\,Jonsson}, {\sl The Nonlinear Optics of Magneto-Optic Media},
 7786   PhD Thesis (Royal Institute of Technology, Stockholm, 2000),
 7787   {ISBN\thinspace91-7170-575-9}.}
 7788   
 7789   \refitem[10]{P.~N. Butcher and D. Cotter, {\sl The Elements of Nonlinear
 7790   Optics} (Cambridge University Press, New York, 1990),
 7791   {ISBN\thinspace0-521-42424-0}.}
 7792   
 7793   \refitem[11]{E.~T.~Whittaker, {\sl A Course of Modern Analysis--An Introduction
 7794   to the General Theory of Infinite Processes and  of Analytic Functions; With
 7795   an Account of the Principal Transcendental Functions}, 1st Edn.
 7796   (Cambridge University Press, Cambridge, 1902).}
 7797   
 7798   \refitem[12]{E.~T.~Whittaker and G.~N.~Watson, {\sl A Course of Modern
 7799   Analysis--An Introduction to the General Theory of Infinite Processes and 
 7800   of Analytic Functions; With an Account of the Principal Transcendental
 7801   Functions}, 4th Reprinted Edn. (Cambridge University Press, Cambridge, 1996),
 7802   ISBN 0-521-58807-3.}
 7803   
 7804   \refitem[13]{P.~F. Byrd and M.~D. Friedman, {\sl Handbook of Elliptic Integrals
 7805   for Engineers and Scientists}, 2nd Edn. (Springer--Verlag, Berlin, 1971),
 7806   ISBN 3-540-05318-2.}
 7807   
 7808   \refitem[14]{M.~McCall, J.~Light\-wave Technol.~{\bf 18}, 236 (2000).}
 7809   
 7810   \refitem[15]{A.~Othonos and K.~Kalli, {\sl Fiber {Bragg} Gratings}
 7811     (Artech House, Boston, 1999), ISBN\thinspace0-89006-344-3.}
 7812   
 7813   @*Index.
 7814   

Return to previous page

Generated by ::viewsrc::

Last modified Wednesday 15 Feb 2023