text:
\section{Analysis}

\subsection{Data Exploration and Visualization}
\label{subsec:Data_exploration_and_visualization}

The pictures have been automatically scraped from the online picture portals Flickr, Google Images and Yandex Images.

They represent single or multiple flowers under various angles, zoom, brightness conditions, life cycle stages, etc.
\begin{center}
	\includegraphics[scale=.25]{./sections/02_analysis/flowers_patchwork.png}
	\captionof{figure}{samples pictures}
\end{center}

The complete set of pictures distribution is as in Fig. \ref{fig:all-images-distribution}:

\begin{flushleft}
	\includegraphics[scale=.5]{./sections/02_analysis/all_images_distribution}
	\captionof{figure}{All images distribution by label}
	\label{fig:all-images-distribution}
\end{flushleft}

We observe that the classes distribution is slightly unbalanced. There is an average of 865 pictures per classes to train the model, which is reasonably enough. The \textit{dandelion} class is the most represented with 1055 pictures. However, this flower variety has the particularity to be represented in 2 radically distinct state: the yellow flowers and the white "blow balls".
For this particular case, it is beneficial to have more sample to expect the model to be able to recognize both \textit{dandelion}'s aspects.

Nevertheless, a significant number of pictures contains other subjects (persons, insects, other flowers, vase) or seem to be miss-classified. Such pictures can potentially impact negatively the model learning. A more detailed approach of the samples selection is described in chapter \fullref{subsec:Data_Preprocessing}

\subsection{Algorithms and Techniques}

\subsubsection{pictures selection and split }

As already mentioned in the previous chapter, a large number of pictures seems inappropriate to train a model. A "blacklisting" approach will be put in place to discard them from the dataset.

On top of that, the selected pictures will be randomly split into three distinct training, validation and testing datasets. The random splitting is made in a stratified fashion in order to preserve the initial classes distribution in each set.

\subsubsection{image augmentation}

Image augmentation will be used to enrich the training and validation sets. This technique consist in modifying the original pictures in order to artificially generate more training samples. The modifications considered in this project consist of flipping, zooming, stretching or shrinking the images.

\subsubsection{Deep Convolutional Neural Network}

A deep convolutional network is a type of neural networks which architecture is designed in so called convolution layers. The principle of forward and back propagation common to neural networks remains. However the main particularity of a convolutional layer is to analyse the picture in small sub-regions and derive patterns from it. The sequencing of convolutional layers result in the identification of patterns increasingly complex. Consequently the patterns identified in the first layers are rather basic (points, stripes, lines,...) and generic to any pictures. On the contrary, the patterns identified by the last layers are more complex (objects, face attributes,...) and are specific to the problem addressed.

\subsubsection{Transfer Learning}

The training of a full CNN requires significant computation resources and time. However, with Transfer Learning, it is possible to use pre-trained models. This techniques presents the double advantage to spare a significant amount of training time and to benefit from the quality of very deep architectures.

Transfer learning consist of loading a pre-trained model, fix its weights, and replace the last layers in order to fit the new given problem.
In this project, we will determine which among three models available in \texttt{Keras} module suits the best for flower classification. Those models have been trained on the \textit{ImageNet} dataset consisting of several million of labelled images representing thousands of objects.

%A deep CNN has to be trained to recognize flowers variety from pictures. Rather than designing and training a full new CNN, we will take advantage of existing reference models by applying transfer learning. The weights of all convolutional layers of the base model will be loaded and frozen as-is. The top layers will be replaced by some of our own in order to specialize the mode to flowers types recognition.

%An important part of this project will be dedicated to determine the most suitable base model to use.

\subsection{Benchmark}
\label{subsec:benchmark}

The benchmark for this project is the "Flowers Species Recognition" work from Yuning Chai, Victor Lempitsky and Andrew Zisserman from the University of Oxford in 2011 \cite{Chai_BiCos, Chai_BiCos_demo} .

This two-steps approach consist of the segmentation of the pictures and the training of a kernelized SVM classifier. The best model reach a prediction accuracy of 80.0\% and is able to recognize flowers among 102 different variety.

The goal of this project is to reach at least this accuracy, however only 5 flower species are considered.


text:
%-------------------------
% Resume in Latex
% Author: Brighton Balfrey
% Original Author : Sourabh Bajaj
% License : MIT
%------------------------

\documentclass[letterpaper,11pt]{article}

\usepackage{latexsym}
\usepackage[empty]{fullpage}
\usepackage{titlesec}
\usepackage{marvosym}
\usepackage[usenames,dvipsnames]{color}
\usepackage{verbatim}
\usepackage{enumitem}
\usepackage[hidelinks]{hyperref}
\usepackage{fancyhdr}
\usepackage[english]{babel}
\usepackage{tabularx}
\input{glyphtounicode}

\pagestyle{fancy}
\fancyhf{} % clear all header and footer fields
\fancyfoot{}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}

% Adjust margins
\addtolength{\oddsidemargin}{-0.5in}
\addtolength{\evensidemargin}{-0.5in}
\addtolength{\textwidth}{1in}
\addtolength{\topmargin}{-.5in}
\addtolength{\textheight}{1.0in}

\urlstyle{same}

\raggedbottom
\raggedright
\setlength{\tabcolsep}{0in}

% Sections formatting
\titleformat{\section}{
  \vspace{-4pt}\scshape\raggedright\large
}{}{0em}{}[\color{black}\titlerule \vspace{-5pt}]

% Ensure that generate pdf is machine readable/ATS parsable
\pdfgentounicode=1

%-------------------------
% Custom commands
\newcommand{\resumeItem}[2]{
  \item\small{
    \textbf{#1}{: #2 \vspace{-2pt}}
  }
}

% Just in case someone needs a heading that does not need to be in a list
\newcommand{\resumeHeading}[4]{
    \begin{tabular*}{0.99\textwidth}[t]{l@{\extracolsep{\fill}}r}
      \textbf{#1} & #2 \\
      \textit{\small#3} & \textit{\small #4} \\
    \end{tabular*}\vspace{-5pt}
}

\newcommand{\resumeSubheading}[4]{
  \vspace{-1pt}\item
    \begin{tabular*}{0.97\textwidth}[t]{l@{\extracolsep{\fill}}r}
      \textbf{#1} & #2 \\
      \textit{\small#3} & \textit{\small #4} \\
    \end{tabular*}\vspace{-5pt}
}

\newcommand{\resumeSubSubheading}[2]{
    \begin{tabular*}{0.97\textwidth}{l@{\extracolsep{\fill}}r}
      \textit{\small#1} & \textit{\small #2} \\
    \end{tabular*}\vspace{-5pt}
}

\newcommand{\resumeSubItem}[2]{\resumeItem{#1}{#2}\vspace{-4pt}}

% Resume subitem
% Second param, however, is Github link
% Example \projectSubItem{Example Project}{http://github.com/example}{This is the description.}
% Will produce: Example Project: This is the description. http://github.com/example
% Where the `Example Project` header and the Github link link to Github
\newcommand{\projectSubItem}[3]{\resumeSubItem{\href{#2}{#1}}{#3 \href{#2}{#2}}}

\renewcommand{\labelitemii}{$\circ$}

\newcommand{\resumeSubHeadingListStart}{\begin{itemize}[leftmargin=*]}
\newcommand{\resumeSubHeadingListEnd}{\end{itemize}}
\newcommand{\resumeItemListStart}{\begin{itemize}}
\newcommand{\resumeItemListEnd}{\end{itemize}\vspace{-5pt}}

%-------------------------------------------
%%%%%%  CV STARTS HERE  %%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

%----------HEADING-----------------
\begin{tabular*}{\textwidth}{l@{\extracolsep{\fill}}r}
  \textbf{\href{https://github.com/brighton1101}{\Large Brighton Balfrey}} & Email : \href{mailto:brighton.balfrey@gmail.com}{brighton.balfrey@gmail.com}\\
    \href{https://github.com/brighton1101}{https://github.com/brighton1101} & Mobile : +1-805-646-4945 \\
\end{tabular*}

%-----------EDUCATION-----------------
\section{Education}
  \resumeSubHeadingListStart
    \resumeSubheading
      {University of Southern California}{Los Angeles, CA}
      {BS in Computer Science and Business Administration}{August 2017 - May 2021}
  \resumeSubHeadingListEnd

%-----------EXPERIENCE-----------------
\section{Experience}
  \resumeSubHeadingListStart

    \resumeSubheading
      {Etsy}{Brooklyn, NY}
      {Software Engineer Intern}{May 2020 - August 2020}
      \resumeItemListStart
        \resumeItem{Knowledge Base}
          {Developed Scala service that consumes various upstream data sources and provides consumers with inferred and known attributes describing listings on Etsy.com, giving enhanced recommendations and product experiences}
        \resumeItem{Infrastructure}
          {Developed background service in Scala to automatically perform redeploys of a critical API service upon notification from upstream Airflow job indicating new data is available, providing consumers with the newest data immediately and cutting down lag in this process by days.}
        \resumeItem{Deployment Tooling}
            {Added validation features to internal Google Cloud deployment tool written in Python for verifying Cloud Storage metadata as part of deployment processs, preventing various Etsy services from being deployed with bad data}
        \resumeItem{Load Testing}
            {Created Python tool during internal hackathon to scale-up load testing of applications by automatically provisioning Google Cloud Compute Engine Instances and running Gatling tests across the VMs in parallel, giving verification that the Knowledge Base service could keep up with Etsy's load}
        \resumeItem{Tech Used}
            {Scala, Python, Terraform, Apache Airflow, Docker, Google Cloud}
      \resumeItemListEnd

% --------Multiple Positions Heading------------
%    \resumeSubSubheading
%     {Software Engineer I}{Oct 2014 - Sep 2016}
%     \resumeItemListStart
%        \resumeItem{Apache Beam}
%          {Apache Beam is a unified model for defining both batch and streaming data-parallel processing pipelines}
%     \resumeItemListEnd
%    \resumeSubHeadingListEnd
%-------------------------------------------

    \resumeSubheading
      {Fandango}{Incline Village, NV/Los Angeles, CA}
      {Software Engineer I (Contract), Software Engineer Intern}{June 2019 - May 2020}
      \resumeItemListStart
        \resumeItem{Activate Rewards}
          {Developed backend platform for managing Fandango's consumer rewards redemptions. Worked on features in conjunction with Fortune 100 customers for custom rewards programs.}
        \resumeItem{Theater Data}
          {Developed new REST endpoint allowing for aggregation of teather data across multiple rewards products allowing consumers to get alternate rewards in response to a major policy change by a vendor affecting thousands of rewards redemptions.}
        \resumeItem{Reporting Tool}
          {Created reporting tool joining previously-disjointed legacy datasets across all Fandango rewards platform products, allowing for better pricing analysis on redemption data across individual rewards promotions.}
        \resumeItem{Image Validation}
          {Developed prototype image validation service to validate rewards redemptions through OCR data parsed from images in serverless AWS technology}
        \resumeItem{Tech Used}
          {PHP, NodeJS, Docker, MySQL, AWS}
      \resumeItemListEnd

    \resumeSubheading
      {University of Southern California}{Los Angeles, CA}
      {Teaching Assistant}{August 2020 - May 2021}
      \resumeItemListStart
        \resumeItem{Teaching Assistant - Advanced Backend Web Development}
          {Only TA for class of ~30 students. Graded coursework, wrote solution code, and gave guest lecture on deploying PHP applications with Docker, Nginx, and a CGI server.}
        \resumeItem{Teaching Assistant - Advanced Frontend Web Development}
          {Only TA for class of ~30 students. Graded coursework, wrote solution code, and created an automated pipeline for grading student repositories on Github Classroom with a command line application written in Go.}
      \resumeItemListEnd

  \resumeSubHeadingListEnd

%-----------PROJECTS-----------------
\section{Projects}
  \resumeSubHeadingListStart
    \projectSubItem{Github notifications CLI}{https://github.com/brighton1101/wnghub}
      {Python command line application that lets users view and configure advanced filters for notifications.}
    \projectSubItem{Yahoo Finance Service}{https://github.com/brighton1101/scala-yahoo-finance-data}
      {Scala application to retrieve and parse data Yahoo Finance HTML documents. Deployed to GCP with Cloud Build and Cloud Functions.}
    \projectSubItem{Personal activity logger CLI}{https://github.com/brighton1101/todayi}
      {Python command line application that allows users to log and tag events throughout the day. Allows users to create filtered reports in CSV, MD, and Github Gists. Pluggable backends including SQLite and pluggable remotes including Google Cloud Storage.}
    \projectSubItem{Apache Airflow}{https://github.com/apache/airflow/pull/12467}
      {Open source contribution to add support for DSS, ECDSA, and Ed25519 private keys in Airflow's SSHHook.}
  \resumeSubHeadingListEnd

%
%--------PROGRAMMING SKILLS------------
%\section{Programming Skills}
%  \resumeSubHeadingListStart
%    \item{
%      \textbf{Languages}{: Scala, Python, Javascript, C++, SQL, Java}
%      \hfill
%      \textbf{Technologies}{: AWS, Play, React, Kafka, GCE}
%    }
%  \resumeSubHeadingListEnd

%-------------------------------------------
\end{document}

ext: tex


text:
\chapter{Problem analysis}
\input{02 - Sections/02-casualties}
%\input{02 - Sections/03-theFocusOnTheIssue}	% KNJ: Working on it, but not needed at the moment.
\input{02 - Sections/03x-phys_geometry}
\input{02 - Sections/04-Mines_and_specifications}
\input{02 - Sections/05-currentMarket}
\input{02 - Sections/05.5-technology}
\input{02 - Sections/06-finalProblemFormulation}
%\input{02 - Sections/07-requirements_old}


text:
% $Id$
% htlatex tex4ht-jsml-xtpipes "xhtml,next,3" "" "-d./"
%
% Copyright (C) 2009-2010 TeX Users Group
% Copyright (C) 2002-2009 Eitan M. Gurari
% Released under LPPL 1.3c+.
% See tex4ht-cpright.tex for license text.

\documentclass{article}
    \Configure{ProTex}{log,<<<>>>,title,list,`,[[]]}
\begin{document}

\input{common}
\input{tex4ht-cpright}

%%%%%%%%%%%%%%%%%%
\part{Script for xtpipes}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%
\section{Outline}
%%%%%%%%%%%%%%%%%%

\AtEndDocument{\OutputCodE\<jsml.4xt\>}

\Needs{"xmllint --valid --noout jsml.4xt"}

\<jsml.4xt\><<<
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xtpipes SYSTEM "xtpipes.dtd" >

<xtpipes signature="jsml.4xt (`version)">
   <sax content-handler="xtpipes.util.ScriptsManager, tex4ht.GroupMn, tex4ht.JsmlFilter"
        lexical-handler="xtpipes.util.ScriptsManagerLH" >
     `<numbers in math`>
     `<special sub and super scripts`>
     `<span frac elements`>
     `<short cut modifiers`>
     `<over and under scripts`>
     `<bold math`>
     `<capital math letters`>
     `<remove multline eqnum cell`>
     `<inline math`>
     `<display math`>
     `<replace characters`>
     `<remove empty split entries`>
     `<boundaries on theorems`>
     `<br into BREAK`>
     `<short notation for empty elements`>
   </sax>
</xtpipes>
>>>

     `<non short tag br elements`>

     `<inline math`>
     `<display math`>
     `<measure tables`>

\<inline math\><<<

>>>

\<display math\><<<

>>>

\<shared display and inline math 1\><<<
`<remove super mn-group`>
`<sayas punctuation`>
`<sayas digits`>
`<sayas math letters`>
`<get content template`>
`<eliminate baseline script marks`>
`<clean begin and mid script marks`>
`<mixed fractions`>
`<'minus' into 'negative'`>
`<compress limit script`>
`<remove scrip indicators from primes`>
`<remove scrip indicators from degree`>
>>>

\<shared display and inline math 2\><<<
`<get content template`>
`<replace nested baseline script marks`>
`<remove marks on empty scripts`>
`<eliminate begin script marks`>
>>>

\AtEndDocument{\OutputCodE\<HtJsml.java\>}

\Needs{"
    javac HtJsml.java -d /home/4/gurari/xtpipes.dir/.
"}

\<HtJsml.java\><<<
package tex4ht;
/* HtJsml.java (`version), generated from `jobname.tex
   Copyright (C) 2009-2010 TeX Users Group
   Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.w3c.dom.*;
public class HtJsml {
  `<HtJsml utility members`>
  `<static void mnGroup(dom)`>
  `<static void fracLevel(dom)`>
  `<static void scriptLevel(dom)`>
  `<static void rootLevel(dom)`>
}
>>>

%%%%%%%%%%%%%%%%%%
\section{Numbers in Math}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Group MN / MO-Punctuation}
%%%%%%%%%%%%%

\AtEndDocument{
   \OutputCodE\<GroupMn.java\>
}
\Needs{"
    javac GroupMn.java -d /home/4/gurari/xtpipes.dir/.
"}

\<GroupMn.java\><<<
package tex4ht;
/* GroupMn.java (`version), generated from `jobname.tex
   Copyright (C) 2009-2010 TeX Users Group
   Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.xml.sax.helpers.*;
import org.xml.sax.*;
import java.io.PrintWriter;

public class GroupMn extends XMLFilterImpl {
     PrintWriter out = null;
     boolean inMn = false;
     String ns;
     int level = -1;
   public GroupMn( PrintWriter out, PrintWriter log, boolean trace){
     this.out = out;
   }
   public void startElement(String ns, String sName,
                           String qName, Attributes attr) {
      level++;
      try{
        if( inMn ){
           if( level == 0 ){ `<consider end of num`> }
        } else { `<consider start of num`> }
        super.startElement(ns, sName, qName, attr);
      } catch( Exception e ){
        System.out.println( "--- GroupMn Error 1 --- " + e);
      }
   }
   public void endElement(String ns, String sName, String qName){
      try{
        if( level < 0) {
          `<endElement: consider end of num`>
        }
        super.endElement(ns, sName, qName);
      } catch( Exception e ){
        System.out.println( "--- GroupMn Error 2 --- " + e);
      }
      level--;
   }
   public void characters(char[] ch, int start, int length){
      try{
        if ( inMn  && (level < 0) ) {
           String s = new String(ch, start, length);
           if (!s.trim().equals("")) {
             inMn = false;
             super.endElement(ns, "mn-group", "mn-group");
        }  }
        super.characters(ch, start, length);
      } catch( Exception e ){
        System.out.println( "--- GroupMn Error 3 --- " + e);
}  }  }
>>>

\<consider start of num\><<<
if( qName.equals( "mn" ) ){
   inMn = true; level = 0;
   Attributes att = new AttributesImpl();
   super.startElement(ns, "mn-group", "mn-group", att);
   this.ns = ns;
} else if( qName.equals( "mo" ) ){
   String cls = attr.getValue( "class" );
   if( (cls != null) && cls.equals("MathClass-punc") ){
      inMn = true; level = 0;
      Attributes att = new AttributesImpl();
      super.startElement(ns, "mn-group", "mn-group", att);
      this.ns = ns;
}  }
>>>

\<consider end of num\><<<
if( !qName.equals( "mn" ) ){
  if( qName.equals( "mo" ) ){
     String cls = attr.getValue( "class" );
     if( (cls == null) || !cls.equals("MathClass-punc") ){
        inMn = false;
        super.endElement(ns, "mn-group", "mn-group");
     }
  } else {
     inMn = false;
     super.endElement(ns, "mn-group", "mn-group");
} }
>>>

\<endElement: consider end of num\><<<
if( inMn ){
   inMn = false;
   super.endElement(ns, "mn-group", "mn-group");
}
>>>

%%%%%%%%%%%%%
\subsection{Outline of Post Original Partition}
%%%%%%%%%%%%%

\<numbers in math\><<<

>>>

\<missed partitions to mn groups\><<<
<dom name="." xml="." method="mnGroup" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>

\<static void mnGroup(dom)\><<<
private static Document dom;
public static void mnGroup(Node d) {
  dom = (Document) d;
  setMnGroup(dom.getFirstChild());
}
private static void setMnGroup(Node node) {
  if( node.getNodeName().equals( "mn-group" ) ){
         boolean bool = false;
    `<get mn characters`>
    if( bool ){
      `<mark remove commas, if comma after period`>
      `<mark remove commas, if not spaced correctly`>
      `<cond remove commas`>
      `<remove punc, on consecutive periods`>
      `<remove punc at end`>
    }
    `<reset mn-group`>
  } else if (node.hasChildNodes()) {
     NodeList children = node.getChildNodes();
     for (int i = 0; i < children.getLength(); i++) {
        Node child = children.item(i);
        if (child.getNodeType() == Node.ELEMENT_NODE) {
           setMnGroup(child);
} }  }  }
>>>

%%%%%%%%%%%%%
\subsection{Mark Partition of MN Group}
%%%%%%%%%%%%%

Consecutive digits and punctation characters are grouped together, and
then ungrouped at characters that are marked by `x'.

\<get mn characters\><<<
NodeList children = node.getChildNodes();
int n = children.getLength();
char [] digit = new char[n];
for (int i = 0; i < n; i++) {
  Node child = children.item(i).getFirstChild();
  if( child == null ){
     digit[i] = 'x';
  } else if( child.getNodeType() != Node.TEXT_NODE ){
     digit[i] = 'x';
  } else {
     String s = child.getNodeValue();
     if( s.length() != 1 ){
       digit[i] = 'x';
     } else {
       char ch = s.charAt(0);
       if(      (ch >= '0') && (ch <= '9') ){
          digit[i] = '0'; bool = true;
       } else if( (ch == '.') || (ch == ',') ){ digit[i] = ch; }
       else                                 { digit[i] = 'x';}
} }  }
>>>

\<<<
bool = false;
for (int i = 0; i < n; i++) {
  if( digit[i] == '.' ){
     for (; i < n; i++) {
       if( digit[i] == ',' ){
          bool = true; break;
     } }
     break;
} }
>>>

\<<<
if( !bool ){
  for (int i = 0; i < n; i++) {
    if( digit[i] == ',' ){
       if( ( ((i+3) >= n)
             || (digit[i+1] != '0')
             || (digit[i+2] != '0')
             || (digit[i+3] != '0')
           )
           ||
           (
             ((i+4) < n) && (digit[i+4] == '0')
           )
           ||
           (
             (i>3) && (digit[i-4] == '0')
           )
       ){  bool = true; break;
       } else { i += 3; }
} } }
>>>

\<cond remove commas\><<<
if( bool ){
  for (int i = 0; i < n; i++) {
    if( digit[i] == ',' ){ digit[i] = 'x'; }
} }
>>>

\<remove punc, on consecutive periods\><<<
bool = false;
for (int i = 0; i < n; i++) {
  if( (digit[i] == 'x')
      || (digit[i] == ',') ){ bool = false; }
  else if( digit[i] == '.' ){
    if( bool ){
       for (int j = 0; j < n; j++) {
         if( (digit[j] == '.') || (digit[j] == ',') ){
            digit[j] = 'x';
       } }
       break;
    }
    bool = true;
} }
>>>

\<remove punc at end\><<<
if( digit[n-1] == '.' ){ digit[n-1] = 'x'; }
>>>

%%%%%%%%%%%%%
\subsection{Realize the Sub Partition}
%%%%%%%%%%%%%

\<reset mn-group\><<<
Node parent = node.getParentNode();
Element g = dom.createElement( "mn-group-s" );
Element cur = dom.createElement( "mn-group" );
for(int i=0;  i<n; i++ ){
   Node child = node.getFirstChild();
   node.removeChild( child );
   if( digit[i] == 'x' ){
      if( cur.hasChildNodes() ){ g.appendChild( cur ); }
      g.appendChild( child );
      cur = dom.createElement( "mn-group" );
   } else {
      cur.appendChild( child );
}  }
if( cur.hasChildNodes() ){ g.appendChild( cur ); }
parent.replaceChild( g, node );
>>>

%%%%%%%%%%%%%
\subsection{Reset MNs}
%%%%%%%%%%%%%

\<merge digits\><<<
<xsl:template match="mn-group" >
   <xsl:choose>
      <xsl:when test=" not(child::mn) ">
        <xsl:apply-templates select="*|text()" />
      </xsl:when>
      <xsl:otherwise>
         <mn>
           <xsl:value-of select="." />
         </mn>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>
>>>

\<remove super mn-group\><<<
<xsl:template match="mn-group-s" >
  <xsl:apply-templates select="*|@*|text()|comment()" />
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Pronounced Letters}
%%%%%%%%%%%%%

\<sayas math letters \><<<
<xsl:template match="mi[ .='a' ]" >
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <SAYAS SUB="aih">a</SAYAS>
  </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Pronounced Punctuation in math}
%%%%%%%%%%%%%

TTSs might ignore punctuation marks. We want these
symbols in math.

\<sayas punctuation\><<<
<xsl:template match="mo[
    (@class='MathClass-punc')
    and ( (.='.') or (.=',')  or (.='!')
          or (.=';') or (.=':') or (.='?') )
]" >
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <BREAK SIZE="small"/>
    <xsl:choose>
       <xsl:when test=" .='.' " >
          <SAYAS SUB="dot">.</SAYAS>
       </xsl:when>
       <xsl:when test=" .=',' " >
          <SAYAS SUB="comma">,</SAYAS>
       </xsl:when>
       <xsl:when test=" .=';' " >
          <SAYAS SUB="semicolon">;</SAYAS>
       </xsl:when>
       <xsl:when test=" .=':' " >
          <SAYAS SUB="colon">:</SAYAS>
       </xsl:when>
       <xsl:when test=" .='!' " >
          <SAYAS SUB="exclamation mark">!</SAYAS>
       </xsl:when>
       <xsl:when test=" .='?' " >
          <SAYAS SUB="question mark">?</SAYAS>
       </xsl:when>
    </xsl:choose>
    <BREAK SIZE="small"/>
  </xsl:copy>
</xsl:template>
>>>

\<sayas digits\><<<
<xsl:template match="mn[
   `<mn modified above`>
   or
   `<mn modified under`>
]" >
  <xsl:copy>
    <SAYAS CLASS="digits">
      <xsl:value-of select="." />
    </SAYAS>
  </xsl:copy>
</xsl:template>
>>>

\<mn modified above\><<<
ancestor::mover[
  not( descendant::*[
        (count( `<math content element`> ) > 1)
     ])
  and
  (
     preceding-sibling::*[1][self::dot or self::mn-group-s]
     or
     following-sibling::*[1][self::dot or self::mn-group-s]
  )
]
>>>

\<mn modified under\><<<
ancestor::munder[
  not( descendant::*[
        (count( `<math content element`> ) > 1)
     ])
  and
  (
     preceding-sibling::*[1][self::dot or self::mn-group-s]
     or
     following-sibling::*[1][self::dot or self::mn-group-s]
  )
]
>>>

%%%%%%%%%%%%%%%%%%
\section{Process Characters}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{'minus' into 'negative'}
%%%%%%%%%%%%%

\<'minus' into 'negative'\><<<
<xsl:template match="mo[
    (@class = 'MathClass-bin')
  and
    ( normalize-space(.) =
      normalize-space(descendant::span[@class = 'ch 2212'])
    )
  and
    (   preceding-sibling::*[1][
             (@title='speech-extra')
             or (@class='MathClass-bin')
             or (@class='MathClass-rel')
             or (@class='MathClass-punc')
             or (@class='MathClass-op')
             or self::mn-group-s [ child::* [
                   (position() = last())
                  and
                   (@class='MathClass-punc')
        ]       ] ]
        and
        (
           following-sibling::*[1][ self::mn-group-s
                                 or self::mi ]
          or
           (count(following-sibling::*[
               not(@title = 'speech-extra')
            ]) = 1)
        )
      or
        not(preceding-sibling::*) and following-sibling::*
    )
]" >
  <xsl:copy>
    <xsl:attribute name="class">
       <xsl:text>mo-unary</xsl:text>
    </xsl:attribute>
    <xsl:apply-templates select="*|text()|comment()"
                         mode="minus-neg" />
  </xsl:copy>
</xsl:template>
>>>

\<'minus' into 'negative'\><<<
<xsl:template match="*|@*|text()|comment()" mode="minus-neg" >
  <xsl:copy>
    <xsl:apply-templates select="*|@*|text()|comment()"
                         mode="minus-neg" />
  </xsl:copy>
</xsl:template>
>>>

\begin{verbatim}
 subscript
<mo class="MathClass-bin">

    minus

</mo>
<mn>2</mn>
\end{verbatim}

\<'minus' into 'negative'\><<<
<xsl:template match="text()" mode="minus-neg" >
  <xsl:choose>
    <xsl:when test=" . = 'minus' " >
      <xsl:text>negative</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="." />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
>>>

%%%%%%%%%%%%%%%%%%
\subsection{Capital Letters in Math}
%%%%%%%%%%%%%%%%%%

\<capital math letters\><<<

>>>

\<<<
<xsl:template match="mi" >
  <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:if test=" string-length(.) = 1 " >
         <xsl:if test="
                     (translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                  '') = '' )
                  " >

               <xsl:text> capital </xsl:text>

         </xsl:if>
      </xsl:if>
      <xsl:apply-templates select="*|text()|comment()" />
  </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Right Apostrophes}
%%%%%%%%%%%%%

\<replace characters\><<<

>>>

\<right apostrophe in prose\><<<
<xsl:template match="span[
     (@class = 'char-del')
    and  child::span [ @class = 'ch 2019' ]
]" >
   <xsl:text>'</xsl:text>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Delimiters on List Marks}
%%%%%%%%%%%%%

\<delimiters in marks of enumerated lists\><<<
<xsl:template match="PROS[  parent::SENT[@class='ol-mark'] ]" >
   <xsl:copy>
      <xsl:apply-templates
           select="*[not(@class='char-del')]|@*|text()|comment()" />
   </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%%%%%%
\section{Clean Up}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Extra Math Pauses}
%%%%%%%%%%%%%

Deletes pauses that are not separated by text from their immediate
predecessors.

An earlier XSLT-based approach was very slow, and died
on nodes with large numbers of children.

\<eliminate extra math pauses\><<<
<sax name="." xml="." content-handler="tex4ht.JsmlMathBreak" />
>>>

\AtEndDocument{
   \OutputCodE\<JsmlMathBreak.java\>
}
\Needs{"
    javac -classpath /home/4/gurari/tex4ht.dir/texmf/tex4ht/bin/tex4ht.jar
          JsmlMathBreak.java
          -d /home/4/gurari/xtpipes.dir/.
"}

\<JsmlMathBreak.java\><<<
package tex4ht;
/* JsmlMathBreak.java (`version), generated from `jobname.tex
   Copyright (C) 2009-2010 TeX Users Group
   Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */

import xtpipes.XtpipesUni;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import java.io.*;
import java.lang.reflect.*;
import java.util.HashMap;

public class JsmlMathBreak extends DefaultHandler {
        PrintWriter out = null;
        boolean delete = false;
  public JsmlMathBreak(PrintWriter out,
                       HashMap<String,Object> scripts,
                       Method method, PrintWriter log, boolean trace) {
    this.out = out;
  }
  public void characters(char[] ch, int start, int length) {
    String s = XtpipesUni.toUni(ch, start, length, "<>&");
    out.print( s );
    if( !s.trim().equals("") ){
       delete = false;
  } }
  public void startElement(String ns, String sName,
                                      String qName,
                                      Attributes atts) {
    if( !( delete && qName.equals("BREAK") ) ){
      String s = "<" + qName + "\n";
      for (int i = 0; i < atts.getLength(); i++) {
        String name = atts.getQName(i);
        if (name != "xmlns") {
          s += (" " + name + "=\""
              + XtpipesUni.toUni(atts.getValue(i), "<>&\"")
              + "\"");
      } }
      if( qName.equals( "BREAK" ) ){
        s += "/";
        delete = true;
      }
      s += ">";
      out.print(s);
  } }
  public void endElement(String ns, String sName, String qName) {
    if( !qName.equals( "BREAK" ) ){
      String s = "</" + qName + ">";
      out.print(s);
} } }
>>>

\begin{verbatim}
  </mrow>

    <BREAK SIZE="medium"/>
    <level prefix="end" depth="1">end end root</level>
    <BREAK SIZE="medium"/>

</mroot>

  <BREAK SIZE="small"/>
  <PROS PITCH="-5">end math</PROS>
  <BREAK SIZE="medium"/>
\end{verbatim}

%%%%%%%%%%%%%
\subsection{Line Breaks}
%%%%%%%%%%%%%

\
<<<

>>>

\<append br with BREAK\><<<
<xsl:template match="br" >
   <xsl:copy>
       <xsl:apply-templates select="@*" />
   </xsl:copy>
   <BREAK SIZE="small"/>
</xsl:template>
>>>
>>>

%%%%%%%%%%%%%%%%%%
\subsection{Empty Elements}
%%%%%%%%%%%%%%%%%%

\marginpar{??????}

Can we avoid empty non-empty representations without of the
following(Example:
\verb+\documentclass{article} \begin{document} \section{Section One} This is Section 1 \end{document} +
)

\<short notation for empty elements\><<<

>>>

\<empty BREAK\><<<
<xsl:template match="BREAK" >
   <xsl:copy>
       <xsl:apply-templates select="@*" />
   </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Empty Array Cells}
%%%%%%%%%%%%%

Empty array celles at end of rows can make it more difficult to
detect deletable baseline indicators.

\<remove multline eqnum cell\><<<

>>>

\<remove multline eqnum cell\><<<

>>>

\<remove empty cells from rows\><<<
<xsl:template match="div[
    (parent::tr or parent::mtr)
    and ( normalize-space(.) = '' )
    and not( normalize-space(following-sibling::*) != '' )
]" >
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Paragraphs (JsmlFilter.java)}
%%%%%%%%%%%%%

\<remove empty paragraphs\><<<
<xsl:template match=" PARA[ normalize-space(.) = '' ] " >
</xsl:template>
>>>

The following adds PARA on `p' paragraphs, ul.

\AtEndDocument{
   \OutputCodE\<JsmlFilter.java\>
}
\Needs{"
    javac JsmlFilter.java -d /home/4/gurari/xtpipes.dir/.
"}

\<JsmlFilter.java\><<<
package tex4ht;
/* JsmlFilter.java (`version), generated from `jobname.tex
   Copyright (C) 2009-2010 TeX Users Group
   Copyright (C) `CopyYear.2002. Eitan M. Gurari
`<TeX4ht copyright`> */
import org.xml.sax.helpers.*;
import org.xml.sax.*;
import java.io.PrintWriter;

public class JsmlFilter extends XMLFilterImpl {
     PrintWriter out = null;
   public JsmlFilter( PrintWriter out, PrintWriter log, boolean trace ){
     this.out = out;
   }
   public void startElement(String ns, String sName,
                           String qName, Attributes attr) {
      try{
        if( `<elements for PARA?`> ){
          Attributes att = new AttributesImpl();
          super.startElement(ns, "PARA", "PARA", att);
        }
        super.startElement(ns, sName, qName, attr);
      } catch( Exception e ){
        System.out.println( "--- JsmlFilter Error 1 --- " + e);
   }  }
   public void endElement(String ns, String sName, String qName){
      try{
        super.endElement(ns, sName, qName);
        if( `<elements for PARA?`> ){
             super.endElement(ns, "PARA", "PARA");
        }
      } catch( Exception e ){
        System.out.println( "--- JsmlFilter Error 2 --- " + e);
}  }  }
>>>

\<elements for PARA?\><<<
   qName.equals( "p" )
|| qName.equals( "h2" )
|| qName.equals( "h3" )
|| qName.equals( "h4" )
|| qName.equals( "ul" )
|| qName.equals( "ol" )
|| qName.equals( "li" )
|| qName.equals( "dd" )
|| qName.equals( "dl" )
>>>

%%%%%%%%%%%%%
\subsection{Remove Split Arrays}
%%%%%%%%%%%%%

\<remove empty split entries\><<<

>>>

\<clean math split\><<<
<xsl:template match=" div[ @class='split-side' ]
" >
    <xsl:variable name="content">
       <xsl:apply-templates select="*" mode="content" />
    </xsl:variable>
    <xsl:if test="
       string-length( normalize-space( $content )) != 0
    " >
       <xsl:copy>
          <xsl:apply-templates select=" *|@*|text()|comment() " />
       </xsl:copy>
    </xsl:if>
</xsl:template>
>>>

%%%%%%%%%%%%%
\section{Eliminate Inline Math Narrative}
%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Core Content of  One Element}
%%%%%%%%%%%%%

\<eliminate inline math narrative NO\><<<
<xsl:template match="span[
    (@class = 'inline-math')
  and
    (count( `<math content element`> ) = 1)
]" >
  <xsl:copy>
    <xsl:choose>
       <xsl:when test="child::mfrac or child::msqrt
                    or child::mover or child::munder
       ">
          <xsl:attribute name="class">
             <xsl:text>semi-math</xsl:text>
          </xsl:attribute>
          <BREAK SIZE="small"/>
          <xsl:apply-templates
              select="`<math content element`>" />
       </xsl:when>
       <xsl:otherwise>
          `<non-adjacent narrative`>
       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>

\<non-adjacent narrative\><<<
<xsl:variable name="content">
   <xsl:apply-templates
       select="`<math content element`>"
         mode="content" />
</xsl:variable>
<xsl:choose>
   `<math narrative of length one`>
   `<math narrative of just one element`>
   `<simple sub or sup`>
   <xsl:otherwise>
      <xsl:apply-templates
                    select="*|@*|text()|comment()" />
   </xsl:otherwise>
</xsl:choose>
>>>

\<math content element\><<<
child::*[ not(@title = 'speech-extra')
          and not( self::BREAK )
        ]
>>>

\<math narrative of length one\><<<
<xsl:when test="
   string-length( normalize-space( $content )) = 1
" >
   <xsl:attribute name="class">
      <xsl:text>semi-math</xsl:text>
   </xsl:attribute>
   <xsl:apply-templates
              select="`<math content element`>" />
</xsl:when>
>>>

\<math narrative of just one element\><<<
<xsl:when test="
   not(`<math content element`>
        / descendant::* [
            count(child::*[
                not(self::BREAK)
            ] ) > 1
          ] )
" >
   <xsl:attribute name="class">
      <xsl:text>semi-math</xsl:text>
   </xsl:attribute>
   <PROS PITCH="-5">
   <BREAK SIZE="small"/>
      <xsl:apply-templates
              select="`<math content element`>" />
   <BREAK SIZE="small"/>
   </PROS>
</xsl:when>
>>>

\<simple sub or sup\><<<
<xsl:when test="  child::*[
     (position() = 2)
   and
     (self::msub or self::msup or self::msubsup)
]" >
    <xsl:variable name="content">
       <xsl:apply-templates
           select="child::*[2] / child::*[
                   (@class = 'mrow-base')
                or (@class = 'limits-mrow-base') ]"
             mode="content" />
    </xsl:variable>
    <xsl:choose>
       <xsl:when test="
          string-length( normalize-space( $content )) = 1
         or
          (translate($content,'0123456789 ','') = '')
       " >
          <xsl:attribute name="class">
             <xsl:text>semi-math</xsl:text>
          </xsl:attribute>
          <PROS PITCH="-5">
          <BREAK SIZE="small"/>
             <xsl:apply-templates select="*[2]" />
          <BREAK SIZE="small"/>
          </PROS>
      </xsl:when>
       <xsl:otherwise>
          <xsl:apply-templates select="*|@*|text()" />
       </xsl:otherwise>
    </xsl:choose>
</xsl:when>
>>>

\begin{verbatim}

  <msub>
    <mrow class="mrow-base">
      <mi>C</mi>
    </mrow>
    <mrow class="mrow-sub">
      <mi>i</mi>
    </mrow>
  </msub>

\end{verbatim}

%%%%%%%%%%%%%
\subsection{Unary Op}
%%%%%%%%%%%%%

The `mo-unary' is established in the first pass over inline-math,
so we need to wait for the second pass with the following.

\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
    (@class = 'inline-math')
  and
    (count( `<math content element`> ) = 2)
  and
    (  child::mo[
          (@class = 'mo-unary')
        and
          following-sibling::*[1]
          / self::mi
       ]
      or
       child::mi[
          following-sibling::*[1]
          [ (@class = 'MathClass-open-close')
            and
            not(child::*[2]
                / child::*[ not(self::BREAK) ]
                / child::*[ not(self::BREAK) ] )
       ]  ]
    )
]" >
  <xsl:copy>
    <xsl:choose>
       `<when func on shallow arg`>
       <xsl:otherwise>
          `<unary op on short content`>
       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>

\<when func on shallow arg\><<<
<xsl:when test="
   child::mrow[ @class = 'MathClass-open-close' ]
" >
   <xsl:attribute name="class">
      <xsl:text>semi-math</xsl:text>
   </xsl:attribute>
   <PROS PITCH="-5">
   <BREAK SIZE="small"/>
      <xsl:apply-templates
              select="`<math content element`>" />
   <BREAK SIZE="small"/>
   </PROS>
</xsl:when>
>>>

\<unary op on short content\><<<
<xsl:attribute name="class">
   <xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
   <xsl:apply-templates
           select="`<math content element`>" />
<BREAK SIZE="small"/>
</PROS>
>>>

%%%%%%%%%%%%%
\subsection{Shallow Expression}
%%%%%%%%%%%%%

\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
    (@class = 'inline-math')
  and
     not( child::*[
         not(self::mo)
         and not(self::mi)
         and not(self::mn)
         and not(self::mn-group-s)
         and not( @title='speech-extra' )
         and not( self::mfrac[
            preceding-sibling::*[1][self::mn ]
           ]
         )
         and not( self::msub
                  / child::*[1][
                       child::mo[ @class = 'MathClass-op' ]
                       and
                       not(child::*[2])
                    ]
         )
     ]  )
]" >
  <xsl:copy>
    `<shallow expression`>
  </xsl:copy>
</xsl:template>
>>>

\<shallow expression\><<<
<xsl:attribute name="class">
   <xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
   <xsl:apply-templates
           select="`<math content element`> | text()" />
<BREAK SIZE="small"/>
</PROS>
>>>

%%%%%%%%%%%%%
\subsection{Shallow Delimited Expression}
%%%%%%%%%%%%%

\<eliminate inline math narrative NO 2\><<<
<xsl:template match="span[
    (@class = 'inline-math')
  and
    (count( `<math content element`> ) = 1)
  and
    child::mrow[ @class='MathClass-open-close' ]
    / child::mrow[
       not( child::*[
         not(self::mo) and not(self::mn-group-s)
         and not(self::mi) and not(self::BREAK)
         and not( @title='speech-extra' )
       ])
    ]
]" >
  <xsl:copy>
    `<shallow delimited expression`>
  </xsl:copy>
</xsl:template>
>>>

\<shallow delimited expression\><<<
<xsl:attribute name="class">
   <xsl:text>semi-math</xsl:text>
</xsl:attribute>
<PROS PITCH="-5">
<BREAK SIZE="small"/>
   <xsl:apply-templates select="mrow" />
<BREAK SIZE="small"/>
</PROS>
>>>

%%%%%%%%%%%%%%%%%%
\section{Superscripts and Subscripts}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Insert Sub-Levels Info}
%%%%%%%%%%%%%

\<set levels for sub and sup scripts\><<<
<dom name="." xml="." method="scriptLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>

\<static void scriptLevel(dom)\><<<
public static void scriptLevel(Node dom) {
   setScriptLevel(dom.getFirstChild(), "");
}
private static void setScriptLevel(Node node, String prefix) {
  String clName = null;
  if (node.hasChildNodes()) {
    if (node.hasAttributes()) {
      Node cl = node.getAttributes().getNamedItem("class");
      if (cl != null) {
        clName = cl.getNodeValue();
        if( clName.equals("mrow-sub")
            ||
            clName.equals("mrow-super")
        ){
          `<append script prefix`>
    } } }
    String ndName = node.getNodeName();
    if(
      ndName.equals("msqrt")
      ||
      ndName.equals("mroot")
    ){  prefix = ""; }
    `<script invoke children`>
} }
>>>

\

>>>

\<<<
<set name="m-sub-sup" >
  `<open xslt script`>
  `<undo if empty su`>
  `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sub-sup" />
>>>

\<<<
<set name="m-sub-sup" >
  `<open xslt script`>
  `<undo if empty su`>
  `<msub of log`>
  `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sub-sup" />
>>>

\<undo if empty su\><<<
<xsl:template match="*[
    (self::msup or self::msub or self::msubsup)
  and
    not(
        child::mrow[ @class = 'mrow-sub' ]
        / child::*[ not(@title = 'speech-extra')
                    and
                    (normalize-space(.) != '')
                  ]
    )
  and
    not(
        child::mrow[ @class = 'mrow-super' ]
        / child::*[ not(@title = 'speech-extra')
                    and
                    (normalize-space(.) != '')
                  ]
    )
]" >
   <xsl:apply-templates select="child::mrow[
                          @class = 'mrow-base' ]/*" />
</xsl:template>
>>>

\begin{verbatim}
<msup>
   <mrow class="mrow-base">
     .........
   </mrow>
   <wrow class="mrow-super">
      superscript
      baseline
   </mrow>
</msup>
\end{verbatim}

%%%%%%%%%%%%%
\section{Special Subscripts and Superscripts}
%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Squared}
%%%%%%%%%%%%%

\<superscript 2 and 3 into verbose\><<<
<set name="m-sup-2-3" >
  `<open xslt script`>
  `<superscript into squared and cube`>
  `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-sup-2-3" />
>>>

\<superscript into squared and cube\><<<
<xsl:template match="msup[
    (normalize-space(
      child::mrow[ (@class = 'mrow-super') ]
        / child::*[ not (@class = 'begin-script')
                    and
                    not (@class = 'end-script')
                  ]
     ) = '2')
  and `<su verbose not on op`>
  and (normalize-space(mrow[@class = 'mrow-base']) != '' )
]" >
   <xsl:copy>
      <xsl:apply-templates select="*|@*|text()|comment()"
                           mode="squared" />
   </xsl:copy>
</xsl:template>
>>>

\<su verbose not on op\><<<
not(
  child::mrow[ @class = 'mrow-base' ]
    / child::span[ not( @title = 'speech-extra' ) ]
                 [ position() = last() ]
    / self::* [ @class = 'mo-op' ]
)
>>>

\<superscript into squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                           mode="squared" >
   <xsl:copy>
     <xsl:choose>
        <xsl:when test=" @class = 'mrow-super' ">
           <xsl:apply-templates select="@*" />
           <mo class="mo-op">
             <xsl:text> squared </xsl:text>
           </mo>
       </xsl:when>
        <xsl:otherwise>
           <xsl:apply-templates select="*|@*|text()" />
        </xsl:otherwise>
     </xsl:choose>
   </xsl:copy>
</xsl:template>
>>>

\begin{verbatim}
<msup>
  <mrow class="mrow-base">
    <mo class="mo-op">cos</mo>
  </mrow>
  <mrow class="mrow-super">
     superscript
    2
     baseline
  </mrow>
</msup>
\end{verbatim}

\<superscript into squared and cube\><<<
<xsl:template match="msup[
    (normalize-space(
      child::mrow[ (@class = 'mrow-super') ]
        / child::*[ not (@class = 'begin-script')
                    and
                    not (@class = 'end-script')
                  ]
     ) = '3')
  and `<su verbose not on op`>
  and (normalize-space(mrow[@class = 'mrow-base']) != '' )
]" >
   <xsl:copy>
      <xsl:apply-templates select="*|@*|text()|comment()"
                           mode="cube" />
   </xsl:copy>
</xsl:template>
>>>

\<superscript into squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                           mode="cube" >
   <xsl:copy>
     <xsl:choose>
        <xsl:when test=" @class = 'mrow-super' ">
           <xsl:apply-templates select="@*" />
           <mo class="mo-op">
             <xsl:text> cube </xsl:text>
           </mo>
        </xsl:when>
        <xsl:otherwise>
           <xsl:apply-templates select="*|@*|text()" />
        </xsl:otherwise>
     </xsl:choose>
   </xsl:copy>
</xsl:template>
>>>

\<<<
<set name="m-subsup-2-3" >
  `<open xslt script`>
  `<subsup into sub squared and cube`>
  `<close xslt script`>
</set>
<xslt name="." xml="." xsl="m-subsup-2-3" />
>>>

\<subsup into sub squared and cube\><<<
<xsl:template match="msubsup[
    (normalize-space(
      child::mrow[ (@class = 'mrow-super') ]
        / child::span[ (@class != 'mid-script')
                       and
                       (@class != 'end-script')
                     ]
     ) = '2')
  and `<su verbose not on op`>
]" >
   <xsl:copy>
      <xsl:attribute name="class" >
         <xsl:text>msub</xsl:text>
      </xsl:attribute>
      <xsl:apply-templates select="*|text()|comment()"
                           mode="sub-squared" />
   </xsl:copy>
</xsl:template>
>>>

\<subsup into sub squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                           mode="sub-squared" >
   <xsl:copy>
     <xsl:choose>
        <xsl:when test=" @class = 'mrow-sub' ">
           <xsl:apply-templates select="*[
                       not( @class = 'end-script' )
                     ]
                           |@*|text()|comment()" />
           <xsl:apply-templates select="
               following-sibling::*[1] / *[
                        @class = 'end-script'
                  ] " />
        </xsl:when>
        <xsl:when test=" @class = 'mrow-super' ">
           <xsl:attribute name="class" >
               <xsl:text>squared-super</xsl:text>
           </xsl:attribute>
           <mo class="mo-op">
             <xsl:text> squared </xsl:text>
           </mo>
        </xsl:when>
        <xsl:otherwise>
           <xsl:apply-templates select="*|@*|text()|comment()" />
        </xsl:otherwise>
     </xsl:choose>
   </xsl:copy>
</xsl:template>
>>>

\<subsup into sub squared and cube\><<<
<xsl:template match="msubsup[
    (normalize-space(
      child::mrow[ (@class = 'mrow-super') ]
        / child::span[ (@class != 'mid-script')
                       and
                       (@class != 'end-script')
                     ]
     ) = '3')
  and `<su verbose not on op`>
]" >
   <xsl:copy>
      <xsl:attribute name="class" >
         <xsl:text>msub</xsl:text>
      </xsl:attribute>
      <xsl:apply-templates select="*|text()|comment()"
                           mode="sub-cube" />
   </xsl:copy>
</xsl:template>
>>>

\<subsup into sub squared and cube\><<<
<xsl:template match="*|@*|text()|comment()"
                           mode="sub-cube" >
   <xsl:copy>
     <xsl:choose>
        <xsl:when test=" @class = 'mrow-sub' ">
           <xsl:apply-templates select="*[
                       not( @class = 'end-script' )
                     ]
                           |@*|text()|comment()" />
           <xsl:apply-templates select="
               following-sibling::*[1] / *[
                        @class = 'end-script'
                  ] " />
        </xsl:when>
        <xsl:when test=" @class = 'mrow-super' ">
           <xsl:attribute name="class" >
               <xsl:text>cube-super</xsl:text>
           </xsl:attribute>
           <mo class="mo-op">
             <xsl:text> cube </xsl:text>
           </mo>
        </xsl:when>
        <xsl:otherwise>
           <xsl:apply-templates select="*|@*|text()|comment()" />
        </xsl:otherwise>
     </xsl:choose>
   </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Numeric Subscripts (Rule 77)}
%%%%%%%%%%%%%

\<compress numeric subscripts\><<<
  <set name="num-sub" >
     `<open xslt script`>
     `<num sub`>
     `<close xslt script`>
  </set>
  <xslt name="." xml="." xsl="num-sub" />
>>>

\<num sub\><<<
<xsl:template match="msub[
  (
    `<num sub on non-primed base`>
    or
    `<num sub on primed base`>
  )
  and
    child::mrow[ @class = 'mrow-sub' ]
    / child::*[ not(@title = 'speech-extra') ][1]
    / self::*[
          normalize-space(.)
          = normalize-space( descendant::mn ) ]
]" >
  <xsl:copy>
     <xsl:apply-templates select="@*" />
     <BREAK SIZE="small"/>
     <xsl:apply-templates select="*[1]" />
     <mrow class="mrow-sub">
        <xsl:apply-templates
           select="*[2] / *[
                    not(@title = 'speech-extra')
          ]" />
        <BREAK SIZE="small"/>
     </mrow>
  </xsl:copy>
</xsl:template>
>>>

\<num sub on non-primed base\><<<
(count( child::mrow[ @class = 'mrow-base' ]
           / child::* ) = 1 )
  and child::mrow[ @class = 'mrow-base' ] / descendant::mi
  and not( ancestor::*[
      self::msub or self::msup or self::msubsup
    ] )
>>>

\<num sub on primed base\><<<
(
  count( child::mrow[ @class = 'mrow-base' ]
        / child::* [
          not(self::BREAK)
        ]
  ) = 2 )
  and child::mrow[ @class = 'mrow-base' ] [
         child::*[1][ self::mi ]
         and
         child::*[
           (position() > 1)
           and
           (normalize-space(.) =
            normalize-space(
               descendant-or-self::span[
                  (@class = 'ch 2032') or (@class = 'ch 2033')
                                 or (@class = 'ch 2034')
               ]
            ))
         ]
      ]
   and not( ancestor::*[
      self::msub or self::msup or self::msubsup
    ] )
>>>

\begin{verbatim}
<msub>
  <mrow class="mrow-base">
    <mi>x</mi>
  </mrow>
  <mrow class="mrow-sub">
     subscript
    <mn>1</mn>
     baseline
  </mrow>
</msub>
\end{verbatim}

\<num sub\><<<
<xsl:template match="msubsup[
  (
    `<num sub on non-primed base`>
  )
  and
    child::mrow[ @class = 'mrow-sub' ]
    / child::*[ not(@title = 'speech-extra') ][1]
    / self::*[
          normalize-space(.)
          = normalize-space( descendant::mn ) ]
]" >
  <msup>
     <BREAK SIZE="small"/>
     <xsl:apply-templates select="*[1]" />
     <mrow class="mrow-sub">
        <xsl:apply-templates
           select="*[2] / *[
                    not(@title = 'speech-extra')
          ]" />
        <BREAK SIZE="small"/>
     </mrow>
     <xsl:apply-templates select="*[3]" />
  </msup>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Primes}
%%%%%%%%%%%%%

\<remove scrip indicators from primes\><<<
<xsl:template match="span[
    (@class = 'begin-script')
  and
    following-sibling::*[ not(@title = 'speech-extra') ] [1]
    / descendant-or-self::*[ not( self::PROS ) ][1]
    /
         child::span / child::span[
            (@class = 'ch 2032') or (@class = 'ch 2033')
                                 or (@class = 'ch 2034')
    ]
]" >
  <BREAK SIZE="small"/>
</xsl:template>
>>>

\<remove scrip indicators from primes\><<<
<xsl:template match="span[
    (@class = 'end-script')
  and
    preceding-sibling::*[ not(@title = 'speech-extra') ] [1]
    / descendant-or-self::*[ not( self::PROS ) ][1]
    /
         child::span / child::span[
            (@class = 'ch 2032') or (@class = 'ch 2033')
                                 or (@class = 'ch 2034')
    ]
]" >
  <BREAK SIZE="small"/>
</xsl:template>
>>>

\begin{verbatim}

    x

     superscript

        double prime

     baseline

\end{verbatim}

\<subsup prime\><<<
<set name="subsup-prime" >
   `<open xslt script`>
   `<compress subsup prime`>
   `<close xslt script`>
</set>
<xslt name="." xml="." xsl="subsup-prime" />
>>>

\<compress subsup prime\><<<
<xsl:template match="msubsup[
    (count(
        child::mrow [ @class='mrow-super' ]
       / child::* [ not(@title = 'speech-extra') ]
    ) = 1)
  and
    not(
        child::mrow [ @class='mrow-super' ]
       / child::* [ not(@title = 'speech-extra') ]
       / descendant::*[ preceding-sibling::*
                        or following-sibling::*]
    )
  and
    child::mrow [ @class='mrow-super' ]
       / child::* [ not(@title = 'speech-extra') ]
       / descendant-or-self::span[ @class='char' ]
       / child::span[
            (@class = 'ch 2032') or (@class = 'ch 2033')
                                 or (@class = 'ch 2034')
         ]
]" >
  <msub>
    <mrow class="mrow-base">
       <xsl:apply-templates select="
             child::mrow[@class = 'mrow-base'] / *
          " />
       <BREAK SIZE="small"/>
       <xsl:apply-templates select="
             child::mrow[@class = 'mrow-super']
             / child::* [ not(@title = 'speech-extra') ]
          " />
    </mrow>
    <mrow class="mrow-sub">
       <xsl:apply-templates
             select="*[@class = 'mrow-sub'] /* " />
       <xsl:apply-templates select="
             child::mrow[@class = 'mrow-super']
             / child::* [ @class = 'end-script' ]
          " />
    </mrow>
  </msub>
</xsl:template>
>>>

\begin{verbatim}

    x

    ......

     superscript

        prime

\end{verbatim}

%%%%%%%%%%%%%
\subsection{Degree}
%%%%%%%%%%%%%

\<remove scrip indicators from degree\><<<
<xsl:template match="mrow[
   (@class = 'mrow-super')
  and
    parent::msup
  and
    (count( `<math content element`> ) = 1)
  and
    `<math content element`> [1][
       normalize-space(.)
       =
       normalize-space(
          descendant::span[@class = 'ch 2218']
       )
    ]
]" >
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:apply-templates
          select="*[not(@title = 'speech-extra')
                    and
                    not(self::BREAK)
                   ]"
                           mode="degree" />
    <BREAK SIZE="small"/>
  </xsl:copy>
</xsl:template>
>>>

\<remove scrip indicators from degree\><<<
<xsl:template match="*" mode="degree" >
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:choose>
       <xsl:when test="self::span[ @class='ch 2218' ]" >
         <xsl:text>degree</xsl:text>
       </xsl:when>
       <xsl:otherwise>
         <xsl:apply-templates
                select="*[not(self::BREAK)]|text()"
                mode="degree"/>
       </xsl:otherwise>
    </xsl:choose>
   </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Logarithms}
%%%%%%%%%%%%%

\<msub of log\><<<
<xsl:template match="
   msub [
    normalize-space(child::*[1]) = 'log'
   or
    normalize-space(child::*[1]) = 'ln'
]" >
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:apply-templates select="child::*[1]" />
    <xsl:apply-templates select="child::*[2]"
                         mode="log" />
  </xsl:copy>
</xsl:template>
>>>

\<msub of log\><<<
<xsl:template match="*" mode="log" >
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:choose>
       <xsl:when test="parent::mrow[ @class = 'mrow-sub' ]" >
         <BREAK SIZE="small"/>
         <xsl:apply-templates select="*" />
         <BREAK SIZE="small"/>

             <xsl:text>of</xsl:text>

         <BREAK SIZE="small"/>
       </xsl:when>
       <xsl:otherwise>
          <xsl:apply-templates
                 select="*[ not(@title = 'speech-extra') ]"
                 mode="log" />
       </xsl:otherwise>
    </xsl:choose>
   </xsl:copy>
</xsl:template>
>>>

\begin{verbatim}
<msub>
  <mrow class="mrow-base">
    <mo class="MathClass-op">log<BREAK SIZE="small"/></mo>
  </mrow>
  <mrow class="mrow-sub">

      ...

    <PROS PITCH="-10">
      <mn>2</mn>
    </PROS>

      ...

  </mrow>
</msub>
<mi>x</mi>
\end{verbatim}

%%%%%%%%%%%%%%%%%%
\section{Fractions (Stage 1)}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Outline}
%%%%%%%%%%%%%

\<<<

>>>

\<frac templates\><<<
<xsl:template match="mfrac" >
  <xsl:copy>
    <xsl:choose>
       `<word fracs`>
       `<prepend continued fractions`>
       `<tail continued fractions`>
       <xsl:otherwise>
         <xsl:apply-templates select="*|@*|text()|comment()" />
       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Word Fractions}
%%%%%%%%%%%%%

Example: `\verb+1 \ove 2+' int `one half'

\<word fracs\><<<
<xsl:when test="
   (string-length(
      normalize-space(child::mrow[ @class = 'mrow-numerator' ][1])
     ) = 1)
   and
   (string-length(
     normalize-space(child::mrow[ @class = 'mrow-enumerator' ][1])
     ) = 1)
">
   `<a := numerator; b := enumerator`>
   <xsl:choose>
      <xsl:when test="
           (translate($a,'123456789','') != '')
           or
           (translate($b,'123456789','') != '')
       " >
         <xsl:apply-templates select="*|@*|text()|comment()" />
      </xsl:when>
      <xsl:when test=" $a < $b ">
         <xsl:attribute  name="class">
             <xsl:text>word-frac</xsl:text>
         </xsl:attribute>
         `<word numerator`>
         `<word enumerator`>
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates select="*|@*|text()|comment()" />
      </xsl:otherwise>
   </xsl:choose>
</xsl:when>
>>>

\<<<
<xsl:variable name="a">
   <xsl:value-of select="
      normalize-space(child::mrow[ @class = 'mrow-numerator' ][1])
   " />
</xsl:variable>
<xsl:variable name="b">
   <xsl:value-of select="
      normalize-space(child::mrow[ @class = 'mrow-enumerator' ][1])
   " />
</xsl:variable>
>>>

\<word numerator\><<<
<xsl:choose>
   <xsl:when test=" $a = 1 "><xsl:text> one </xsl:text></xsl:when>
   <xsl:when test=" $a = 2 "><xsl:text> two </xsl:text></xsl:when>
   <xsl:when test=" $a = 3 "><xsl:text> three </xsl:text></xsl:when>
   <xsl:when test=" $a = 4 "><xsl:text> four </xsl:text></xsl:when>
   <xsl:when test=" $a = 5 "><xsl:text> five </xsl:text></xsl:when>
   <xsl:when test=" $a = 6 "><xsl:text> six </xsl:text></xsl:when>
   <xsl:when test=" $a = 7 "><xsl:text> seven </xsl:text></xsl:when>
   <xsl:when test=" $a = 8 "><xsl:text> eight </xsl:text></xsl:when>
   <xsl:when test=" $a = 9 "><xsl:text> nine </xsl:text></xsl:when>
</xsl:choose>
>>>

\<word enumerator\><<<
<xsl:choose>
   <xsl:when test=" $b = 2 "><xsl:text> half</xsl:text></xsl:when>
   <xsl:when test=" $b = 3 "><xsl:text> third</xsl:text></xsl:when>
   <xsl:when test=" $b = 4 "><xsl:text> fourth</xsl:text></xsl:when>
   <xsl:when test=" $b = 5 "><xsl:text> fifth</xsl:text></xsl:when>
   <xsl:when test=" $b = 6 "><xsl:text> sixth</xsl:text></xsl:when>
   <xsl:when test=" $b = 7 "><xsl:text> seventh</xsl:text></xsl:when>
   <xsl:when test=" $b = 8 "><xsl:text> eighth</xsl:text></xsl:when>
   <xsl:when test=" $b = 9 "><xsl:text> nineth</xsl:text></xsl:when>
</xsl:choose>
<xsl:if test=" $a > 1 "><xsl:text>s</xsl:text></xsl:if>
<xsl:text> </xsl:text>
>>>

%%%%%%%%%%%%%
\subsection{Mixed Fractions}
%%%%%%%%%%%%%

Examples: `\verb+2{3\over 4}+'
into `2 and three forth',
and `\verb+10{25\over 39}+' into `10 and 25 over 39'.

\<mixed fractions\><<<
<xsl:template match="mfrac[
   (
      (translate(
         concat(
           mrow[ (@class = 'mrow-numerator')],
           mrow[ (@class = 'mrow-enumerator')]
         )  ,'0123456789','') = '')
      and
         not(descendant::*/descendant::*
                          /descendant::mn-group-s)
      or
         (@class = 'word-frac')
   )
   and
     preceding-sibling::*[1]
       / self::mn-group-s[ child::*[
            (position() = last())
            and
            self::mn
         ] ]
 ]" >
  <xsl:text> and </xsl:text>
  <xsl:copy>
    <xsl:apply-templates select="*|@*|text()|comment()" />
  </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Continued Fractions Conditions (Rule 69)}
%%%%%%%%%%%%%

\begin{verbatim}
          1
1 + ---------------------------------------
              1
    2 + ---------------------------------------
                  1
        2 + ---------------------------------------
              2 + ...
\end{verbatim}

The fractions are processed recusrively from inside out.  The `tail'
is the one to discover the inner most part of a continued fraction
(i.e., the bottom rows).  Higher levels add to the nucleous built
already under them.

In Stage 1 the members of the continued fractions are marked as
such. In the second stage they being are procesed.

The minimum conditions here are three un-interrupted levels of
fractions.

\begin{verbatim}
<mfrac>
   <mrow class="mrow-enumerator">
      <mn>1</mn>
      <mo class="MathClass-bin">...</mo>
      <mfrac>
        begin fraction
        <mrow class="mrow-numerator"> ... </mrow>
        over
        <mrow class="mrow-enumerator">...</mrow>
        end fraction
      </mfrac>
\end{verbatim}

\<<<
<xsl:variable name="a">
   <xsl:apply-templates select="
         child::mrow[ @class = 'mrow-enumerator' ] /
         child::mfrac /
         preceding-sibling::*[2]
   "  mode="enum-op" />
</xsl:variable>
<xsl:variable name="b">
   <xsl:apply-templates select="
         child::mrow[ @class = 'mrow-enumerator' ] /
         child::mfrac /
         child::mrow[ @class = 'mrow-enumerator' ] /
         child::mfrac /
         preceding-sibling::*[2]
   "  mode="enum-op" />
</xsl:variable>
<xsl:variable name="c">
   <xsl:value-of select="
    normalize-space(
      child::mrow[ @class = 'mrow-enumerator' ] /
      child::mfrac /
      child::mrow[ @class = 'mrow-enumerator' ] /
      child::mfrac /
      child::mrow[ @class = 'mrow-enumerator' ] )
   "  />
</xsl:variable>
>>>

\<frac templates\><<<
<xsl:template match="*" mode="enum-op">
   <xsl:if test="preceding-sibling::*" >
      <xsl:apply-templates select=" preceding-sibling::*[1] " />
   </xsl:if>
   <xsl:value-of select="." />
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Nucleous of Continued Fractions}
%%%%%%%%%%%%%

We are looking for the three most internal (bottom) fractions that
belong to a continued fraction.

\<tail continued fractions\><<<
<xsl:when test="          `%check numeral numerator`%
   (translate(
      normalize-space(
      child::mrow[ @class = 'mrow-numerator' ]),
                              '0123456789','')= '')
   and `<check equality of numerators`>
   and `<check ops before two top fracs`>
">
  `<a,b := top 2 pre op values`>
  <xsl:choose>
     <xsl:when test="
         ( translate($a,'0123456789 ','') = '')
         and (normalize-space($a)=normalize-space($b))
         and starts-with( $c, normalize-space( $a ))
         and starts-with(
               normalize-space(
                 substring-after( $c, normalize-space( $a )) )
               ,
               normalize-space(
                    child::mrow[ @class = 'mrow-enumerator' ] /
                    child::mfrac /
                    preceding-sibling::*[1]                  )
             )
     " >
         <xsl:attribute name="class">
            <xsl:value-of select=" 'continued-mfrac' " />
         </xsl:attribute>
         <xsl:apply-templates select="*|text()|comment()" />
     </xsl:when>
     <xsl:otherwise>
         <xsl:apply-templates select="*|@*|text()|comment()" />
     </xsl:otherwise>
  </xsl:choose>
</xsl:when>
>>>

\<check equality of numerators\><<<
(  normalize-space(
   child::mrow[ @class = 'mrow-numerator' ])
  and
   normalize-space(
   child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   child::mrow[ @class = 'mrow-numerator' ])
)
and
(  normalize-space(
   child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   child::mrow[ @class = 'mrow-numerator' ])
  and
   normalize-space(
   child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   child::mrow[ @class = 'mrow-numerator' ])
)
>>>

\<check ops before two top fracs\><<<
(  child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   preceding-sibling::*[1][@class = 'MathClass-bin']
)
and
(  normalize-space(
   child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   preceding-sibling::*[1] )
   =
   normalize-space(
   child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   child::mrow[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   preceding-sibling::*[1] )
)
>>>

%%%%%%%%%%%%%
\subsection{Prepend Existing Continued Fractions}
%%%%%%%%%%%%%

\<prepend continued fractions\><<<
<xsl:when test="
      self::mfrac
    and
      child::mrow[ @class = 'mrow-enumerator' ]
        / child::mfrac[ @class = 'continued-mfrac' ]
    and
      ( normalize-space(
          child::mrow[ @class = 'mrow-numerator' ]
        )
        =
        normalize-space(
          child::mrow[ @class = 'mrow-enumerator' ]
           / child::mfrac[ @class = 'continued-mfrac' ]
           / child::mrow[ @class = 'mrow-numerator' ]
        )
      )
    and `<check equality of op with cont frac`>
" >
  `<a,b := cont top 2 pre op values`>
  <xsl:choose>
     <xsl:when test="
         normalize-space($a)=normalize-space($b)
     " >
         <xsl:attribute name="class">
            <xsl:value-of select=" 'continued-mfrac' " />
         </xsl:attribute>
         <xsl:apply-templates select="*|text()|comment()" />
     </xsl:when>
     <xsl:otherwise>
         <xsl:apply-templates select="*|@*|text()|comment()" />
     </xsl:otherwise>
  </xsl:choose>
</xsl:when>
>>>

\<check equality of op with cont frac\><<<
(
   normalize-space(
   child::span[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   preceding-sibling::*[1] )
   =
   normalize-space(
   child::span[ @class = 'mrow-enumerator' ] /
   child::mfrac /
   child::span[ @class = 'mrow-enumerator' ] /
   child::span[ @class = 'continued-mfrac' ] /
   preceding-sibling::*[1] )
)
>>>

\<<<
<xsl:variable name="a">
   <xsl:apply-templates select="
         child::span[ @class = 'mrow-enumerator' ] /
         child::span[ @class = 'mcontinued-mfrac' ] /
         preceding-sibling::*[2]
   "  mode="enum-op" />
</xsl:variable>
<xsl:variable name="b">
   <xsl:apply-templates select="
         child::span[ @class = 'mrow-enumerator' ] /
         child::span[ @class = 'mcontinued-mfrac' ] /
         child::span[ @class = 'mrow-enumerator' ] /
         child::span[
           self::mfrac or (@class = 'mcontinued-mfrac')
         ] /
         preceding-sibling::*[2]
   "  mode="enum-op" />
</xsl:variable>
>>>

%%%%%%%%%%%%%%%%%%
\section{Fractions (Stage 2)}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Outline}
%%%%%%%%%%%%%

\<set levels for hyper complex fracs\><<<
<dom name="." xml="." method="fracLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>

\<static void fracLevel(dom)\><<<
public static void fracLevel(Node d) {
   dom = (Document) d;
   setFracLevel(dom.getFirstChild(), 0);
}
private static int setFracLevel(Node node, int cont) {
  int level = 0;
  if (node.hasChildNodes()) {
        String ndName = node.getNodeName();
    int prevCont = cont;
    String clValue = null;
    if (ndName.equals("mfrac")) {
      `<clValue := class of mfrac`>
      `<cont := distance from mfrac(continued-frac)`>
    }
    `<level += inherited from children`>
    `<return 0 if barier`>
    if (ndName.equals("mfrac")) {
      `<return 0 if mfrac barier`>
      if( cont > 0 ){
          if ( prevCont == 0 ){
             `<set start continued fracs mark`>
          }
          `<remove end of non-tail continued frac`>
          level = 0;
      } else if ( prevCont > 0 ){
          `<set end continued fracs mark`>
          level = 0;
      } else
        if( level > 0 ){
          `<set extra levels for frac`>
        }
        level++;
  } }
  return level;
}
>>>

%%%%%%%%%%%%%%%%%%
\subsection{Level Indicators for Nesting (Hyper Complex Fractions)}
%%%%%%%%%%%%%%%%%%

\begin{verbatim}
                  ${a\over b}\over c$

begin begin fraction
                     begin fraction   a
                     over             b
                     end fraction
over over          c
end end fraction
\end{verbatim}

\<set extra levels for frac\><<<
for (int i = 0; i < children.getLength(); i++) {
   Node child = children.item(i);
   if (child.getNodeType() == Node.ELEMENT_NODE) {
      Node cls = child.getAttributes()
                      .getNamedItem("class");
      if (cls != null) {
         String clsName = cls.getNodeValue();
         if (clsName.equals("begin-end")) {
            insertLevelPrefix(child, level);
}  }  }  }
>>>

\<HtJsml utility members\><<<
private static void insertLevelPrefix(Node node, int level){
   if( level == 0 ){ return; }
   if (node.getNodeType() == Node.ELEMENT_NODE) {
     if( node.getNodeName().equals( "level" ) ){
        `<insert level prefixes`>
     } else {
        NodeList children = node.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
           Node child = children.item(i);
           insertLevelPrefix(child, level);
}  }  } }
>>>

\<insert level prefixes\><<<
Node attr = node.getAttributes().getNamedItem("prefix");
if( attr != null ){
  String prefix = attr.getNodeValue();
  String  s = "";
  for(int j=0; j<level; j++){
     s += prefix + " ";
  }
  ((org.w3c.dom.Element) node).setAttribute( "depth", ""+level);
  Node child = node.getFirstChild();
  if( child != null ){
     node.insertBefore( dom.createTextNode(s), child );
} }
>>>

\<level += inherited from children\><<<
NodeList children = node.getChildNodes();
int max = 0;
for (int i = 0; i < children.getLength(); i++) {
   Node child = children.item(i);
   if (child.getNodeType() == Node.ELEMENT_NODE) {
      int d = setFracLevel(child,
                           `<continued level counter`>);
      if (d > max) { max = d; }
}  }
level += max;
>>>

%%%%%%%%%%%%%
\subsection{Level Terminators: Scripts, Word Fracs}
%%%%%%%%%%%%%

\<return 0 if barier\><<<
if(    ndName.equals("msub")
    || ndName.equals("msup")
    || ndName.equals("msubsup")
) {
   return 0;
}
>>>

\<return 0 if mfrac barier\><<<
if( (clValue != null) && clValue.equals("word-frac")
) {
   return 0;
}
>>>

%%%%%%%%%%%%%
\subsection{Bookeeping for Continued Fractions}
%%%%%%%%%%%%%

\<continued level counter\><<<
cont
>>>

In the first phase, the mfrac elements in a group carry
attributes as in

\begin{verbatim}
       <mfrac class="continued-mfrac">
\end{verbatim}

with the exception of the bottom (internal) most leveles.
The `cont' parameter is for determining whether the parent and the
grandparent are frac elements marked as continued.

\<clValue := class of mfrac\><<<
if (node.hasAttributes()) {
   Node cl = node.getAttributes().getNamedItem("class");
   if (cl != null) { clValue = cl.getNodeValue(); }
}
>>>

\<cont := distance from mfrac(continued-frac)\><<<
if( (clValue != null)
    && clValue.equals("continued-mfrac") ) {
  cont = 2;
} else { cont--; }
>>>

%%%%%%%%%%%%%
\subsection{Modifications for Continued Fractions}
%%%%%%%%%%%%%

\<remove end of non-tail continued frac\><<<
Node child = node.getLastChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
   Node cls = child.getAttributes() .getNamedItem("class");
   if (cls != null) {
      String clsName = cls.getNodeValue();
      if ( clsName.equals("begin-end")) {
         node.removeChild( child  );
}  }  }
>>>

\<set end continued fracs mark\><<<
Node child = node.getLastChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
   Node cls = child.getAttributes() .getNamedItem("class");
   if (cls != null) {
      String clsName = cls.getNodeValue();
      if ( clsName.equals("begin-end")) {
         setContinuedNote(child);
}  }  }
>>>

\<set start continued fracs mark\><<<
Node child = node.getFirstChild();
if (child.getNodeType() == Node.ELEMENT_NODE) {
   Node cls = child.getAttributes() .getNamedItem("class");
   if (cls != null) {
      String clsName = cls.getNodeValue();
      if ( clsName.equals("begin-end")) {
         setContinuedNote(child);
}  }  }
>>>

\<HtJsml utility members\><<<
private static void setContinuedNote(Node node){
   if (node.getNodeType() == Node.ELEMENT_NODE) {
     if( node.getNodeName().equals( "level" ) ){
        `<fix end continued note`>
     } else {
        NodeList children = node.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
           Node child = children.item(i);
           setContinuedNote(child);
}  }  } }
>>>

\<fix end continued note\><<<
Node attr = node.getAttributes().getNamedItem("continued");
if (attr != null) {
  node = node.getFirstChild();
  if( node != null ){
     ((org.w3c.dom.Text) node).setData( attr.getNodeValue() );
} }
>>>

%%%%%%%%%%%%%
\section{Set Levels on Roots}
%%%%%%%%%%%%%

\<set levels for roots\><<<
<dom name="." xml="." method="rootLevel" class="tex4ht.HtJsml" />
`<remove xml declaration`>
>>>

\<static void rootLevel(dom)\><<<
public static void rootLevel(Node d) {
   dom = (Document) d;
   setRootLevel(d.getFirstChild());
}
private static int setRootLevel( Node node ){
  int level = 0;
//  String clName = null;
  if (node.hasChildNodes()) {
    `<count root levels inherited from children`>
    String ndName =  node.getNodeName();
    `<block for roots`>
    if( ndName.equals("msqrt") || ndName.equals("mroot") ){
        `<set extra levels for roots`>
        level++;
  } }
  return level;
}
>>>

\<count root levels inherited from children\><<<
NodeList children = node.getChildNodes();
int max = 0;
for (int i = 0; i < children.getLength(); i++) {
  Node child = children.item(i);
  if (child.getNodeType() == Node.ELEMENT_NODE) {
    int d = setRootLevel(child);
    if( d > max ){ max = d; }
} }
level += max;
>>>

\<block for roots\><<<
if( ndName.equals("msub") || ndName.equals("msup") ||
    ndName.equals("msubsup")
) {
   return 0;
}
>>>

\<set extra levels for roots\><<<
for (int i = 0; i < children.getLength(); i++) {
  Node child = children.item(i);
  if (child.getNodeType() == Node.ELEMENT_NODE) {
    Node cls = child.getAttributes()
                    .getNamedItem("class");
    if (cls != null) {
      String clsName = cls.getNodeValue();
      if( clsName.equals("begin-root")
          || clsName.equals("mid-root")
          || clsName.equals("end-root")
      ){
         insertLevelPrefix(child, level);
} } } }
>>>

%%%%%%%%%%%%%
\section{Modifiers}
%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%
\subsection{Over and Under Limit Scripts}
%%%%%%%%%%%%%%%%%%

\<over and under scripts\><<<

>>>

\<over and under scripts\><<<

>>>

\<over and under scripts\><<<

>>>

\<smash over and under scripts\><<<
<xsl:template match="*[
       (@class = 'limits-msub-msup')
     and
       child::*[ (position() = 1)
                 and (@class = 'limits-mrow-base')
                 and child::*[ (position() = 1)
                         and (@class = 'limits-msub-msup')
       ]             ]
]" >
  <xsl:copy>
     <xsl:apply-templates select="@*" />
     <xsl:apply-templates select="
                   *[1]
                   / *[1]
                   / *[ not(@class='limits-mrow-super') ]  " />
     <xsl:apply-templates select=" *[
                   preceding-sibling::*
                 and
                   not(@class='limits-mrow-super') ]" />
     <xsl:apply-templates select="
                   *[1]
                   / *[1]
                   / *[@class='limits-mrow-super' ]  " />
     <xsl:apply-templates select=" *[
                   preceding-sibling::*
                 and
                   (@class='limits-mrow-super') ]" />
  </xsl:copy>
</xsl:template>
>>>

\<compress limit script\><<<
<xsl:template match="span[ @class = 'end-limits-script' ]" >
  <xsl:if test=" parent::*[ not(following-sibling::*) ] ">
    <xsl:copy>
       <xsl:apply-templates select=" @* " />
       <xsl:choose>
          <xsl:when test="
                parent::*[ preceding-sibling::mrow[
                                  @class != 'limits-mrow-base'
                         ]  ]
            " >
            <BREAK SIZE="small"/>
            <xsl:text> end scripts </xsl:text>
            <BREAK SIZE="small"/>
          </xsl:when>
          <xsl:otherwise>
            <BREAK SIZE="small"/>
            <xsl:text> end script </xsl:text>
            <BREAK SIZE="small"/>
          </xsl:otherwise>
       </xsl:choose>
    </xsl:copy>
  </xsl:if>
</xsl:template>
>>>

\<compress limit script\><<<
<xsl:template match="span[ @class = 'begin-limits-script' ]" >
    <xsl:copy>
       <xsl:apply-templates select=" @* " />
       <xsl:choose>
          <xsl:when test="
                parent::*[ @class = 'limits-mrow-super'  ]
          " >
              <xsl:apply-templates
                  select=" parent::*
                           / preceding-sibling::*[1] "
                  mode = "extra-over" />
          </xsl:when>
          <xsl:when test="
                parent::*[ @class = 'limits-mrow-sub'  ]
          " >
              <xsl:apply-templates
                  select=" parent::*
                           / preceding-sibling::*[1] "
                  mode = "extra-under" />
          </xsl:when>
       </xsl:choose>
       <xsl:apply-templates select="*|text()|comment()" />
    </xsl:copy>
</xsl:template>
>>>

\<compress limit script\><<<
<xsl:template match="*" mode="extra-over" >
   <xsl:if   test = " self::mrow[ @class = 'limits-mrow-super' ] " >
     <xsl:text> over </xsl:text>
     <xsl:apply-templates select=" preceding-sibling::*[1] "
                    mode = "extra-over" />
   </xsl:if>
</xsl:template>
>>>

\<compress limit script\><<<
<xsl:template match="*" mode="extra-under" >
   <xsl:if   test = " self::mrow[ @class = 'limits-mrow-sub' ] " >
     <xsl:text> under </xsl:text>
     <xsl:apply-templates select=" preceding-sibling::*[1] "
                    mode = "extra-under" />
   </xsl:if>
</xsl:template>
>>>

%%%%%%%%%%%%%
\subsection{Short Cuts for Math Underline}
%%%%%%%%%%%%%

\<short cut modifiers\><<<

>>>

\<under modifier templates\><<<
<xsl:template match="munder[
    (@class = 'munder-underline')
   and
    child::mrow[
       (@class = 'mo-0332')
       and
       descendant::mi
   ]
]" >
    <xsl:variable name="content">
       <xsl:apply-templates select="*" mode="content" />
    </xsl:variable>
    <xsl:choose>
       <xsl:when test="
          string-length( normalize-space( $content )) = 1
       " >
           <xsl:copy>
              <xsl:apply-templates select="@*" />
              <xsl:apply-templates
                 select=" *[ @class != 'begin-end' ] " />

                 <BREAK SIZE="small"/>
                 <xsl:text> under bar </xsl:text>
                 <BREAK SIZE="small"/>

           </xsl:copy>
       </xsl:when>
       <xsl:otherwise>
          `<set munder`>
       </xsl:otherwise>
    </xsl:choose>
</xsl:template>
>>>

The following code makes to push the munder's under the mover's.

\<set munder\><<<
<xsl:choose>
   <xsl:when test="child::mrow / child::mover">
         <xsl:apply-templates select="child::mrow / child::mover"
                                mode="under-mover" />
   </xsl:when>
   <xsl:otherwise>
     <xsl:copy>
        <xsl:apply-templates select=" *|@*|text() " />
     </xsl:copy>
   </xsl:otherwise>
</xsl:choose>
>>>

\<under modifier templates\><<<
<xsl:template match="*" mode="under-mover" >
   <xsl:choose>
      <xsl:when test="self::mover">
         <xsl:copy>
           <xsl:apply-templates select="@*" />
           <xsl:apply-templates select="*" mode="under-mover" />
         </xsl:copy>
      </xsl:when>
      <xsl:when test="self::mrow[ parent::mover ]">
         <xsl:copy>
           <xsl:apply-templates select="@*" />
           `<cont under-mover`>
         </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates select="." />
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>
>>>

\<cont under-mover\><<<
<xsl:choose>
   <xsl:when test="child::mover">
      <xsl:apply-templates select="*" mode="under-mover" />
   </xsl:when>
   <xsl:otherwise>
      <munder class="munder-underline">
         `<munder prefix`>
         <mrow class="mo-0032">
            <xsl:apply-templates select="*"  />
         </mrow>
         `<munder postfix`>
      </munder>
   </xsl:otherwise>
</xsl:choose>
>>>

\<munder prefix\><<<
<xsl:apply-templates select="
  ancestor::munder[1] / child::*[following-sibling::mrow]
"/>
>>>

\<munder postfix\><<<
<xsl:apply-templates select="
  ancestor::munder[1] / child::*[preceding-sibling::mrow]
"/>
>>>

\begin{verbatim}
<munder class="munder-underline">
   modified under
  <mrow class="mo-0332">
    <mi>x</mi>
  </mrow>
   with bar
</munder>
\end{verbatim}

%%%%%%%%%%%%%
\subsection{Short Cuts for Math Overline}
%%%%%%%%%%%%%

\<short cut modifiers\><<<

>>>

\<over modifier templates\><<<
<xsl:template match="mover[
    (@class = 'mover-overline')
   and
    child::mrow[
       (@class = 'mo-00AF')
       and
       descendant::mi
   ]
]" >
    <xsl:variable name="content">
       <xsl:apply-templates select="*" mode="content" />
    </xsl:variable>
    <xsl:choose>
       <xsl:when test="
          string-length( normalize-space( $content )) = 1
       " >
          `<set mover short cut`>
       </xsl:when>
       <xsl:otherwise>
          <xsl:copy>
             <xsl:apply-templates select="@*" />
             <xsl:apply-templates
                     select="*|text()|comment()" />
          </xsl:copy>
       </xsl:otherwise>
    </xsl:choose>
</xsl:template>
>>>

The following code makes to push the mover's under the munder's.

\<set mover short cut\><<<
<BREAK SIZE="small"/>
<xsl:choose>
   <xsl:when test="child::mrow / child::munder">
         <xsl:apply-templates select="child::mrow / child::munder"
                       mode="under-munder" />
   </xsl:when>
   <xsl:otherwise>
     <xsl:copy>
       <xsl:apply-templates select="@*" />
       <xsl:apply-templates
           select=" *[ @class != 'begin-end' ] " />
         `<mover bar short cut`>
     </xsl:copy>
   </xsl:otherwise>
</xsl:choose>
>>>

\<over modifier templates\><<<
<xsl:template match="*" mode="under-munder" >
   <xsl:choose>
      <xsl:when test="self::munder">
         <xsl:copy>
           <xsl:apply-templates select="@*" />
           <xsl:apply-templates select="*" mode="under-munder" />
         </xsl:copy>
      </xsl:when>
      <xsl:when test="self::mrow[ parent::munder ]">
         <xsl:copy>
           <xsl:apply-templates select="@*" />
           `<cont under-munder`>
         </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates select="." />
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>
>>>

\<cont under-munder\><<<
<xsl:choose>
   <xsl:when test="child::munder">
      <xsl:apply-templates select="*" mode="under-munder" />
   </xsl:when>
   <xsl:otherwise>
      <mover class="mover-overline">
         <mrow class="mo-00AF">
            <xsl:apply-templates select="*"  />
         </mrow>
         `<mover bar short cut`>
      </mover>
   </xsl:otherwise>
</xsl:choose>
>>>

\<mover bar short cut\><<<

   <BREAK SIZE="small"/>
   <xsl:text> over bar </xsl:text>
   <BREAK SIZE="small"/>

>>>

\begin{verbatim}
<mover class="mover-overline">
   modified above
  <mrow class="mo-00AF">

       bold
      <mi class="mi">
           capital
          Z
      </mi>

  </mrow>
   with bar
</mover>
\end{verbatim}

%%%%%%%%%%%%%
\section{New Theorems}
%%%%%%%%%%%%%

\<boundaries on theorems\><<<

>>>

\<annotate bounderies of theorems\><<<
<xsl:template match="
    div[   (@class='newtheorem')
         and
           descendant::*[ self::p ][1]
           / descendant::*[ self::span ][1]
                          [ @class = 'theorem-head' ]
    ]
" >
   <xsl:copy>
     <xsl:apply-templates select="*|@*|text()|comment()" />

        <BREAK SIZE="small"/>
        <xsl:value-of select="
           concat( ' end ',
              substring-before(`<new theorem header`>, ' ')
           ) " />

   </xsl:copy>
</xsl:template>
>>>

\<new theorem header\><<<
concat(
  normalize-space(
    string(
       descendant::*[ self::p ][1]
       / descendant::*[ self::span ][1]
                      [ @class = 'theorem-head' ]
  ) )
  , ' '
)
>>>

%%%%%%%%%%%%%%%%%%
\section{Shared}
%%%%%%%%%%%%%%%%%%

\<open xslt script\><<<
<![CDATA[
   <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   >
      <xsl:output omit-xml-declaration = "yes" />
>>>

\<close xslt script\><<<
      <xsl:template match="*|@*|text()|comment()" >
        <xsl:copy>
          <xsl:apply-templates select="*|@*|text()|comment()" />
        </xsl:copy>
      </xsl:template>
   </xsl:stylesheet>
]]>
>>>

\<get content template\><<<
<xsl:template match="*" mode="content" >
  <xsl:choose>
     <xsl:when test=" @class = 'char' " >
       <xsl:if test="not( child::*[
            (@class = 'ch 2032') or (@class = 'ch 2033')
                                 or (@class = 'ch 2034')
       ] )">
         <xsl:text>x</xsl:text>
       </xsl:if>
     </xsl:when>
     <xsl:when test=" not(
            (@title = 'speech-extra') or (@class = 'accent-char')
         ) " >
       <xsl:apply-templates select="*|text()" mode="content" />
     </xsl:when>
  </xsl:choose>
</xsl:template>
>>>

\marginpar{Can dom be prevented from creating an xml declaration in
  the output? The xslt part is there just to remove the undesirable
  declaration.}

\<remove xml declaration\><<<
<set name="rmXmlDecl" >
  `<open xslt script`>
  `<close xslt script`>
</set>
<xslt name="." xml="." xsl="rmXmlDecl" />
>>>

\AtEndDocument{\Needs{%
    "cd /home/4/gurari/xtpipes.dir
     ;
     jar cf tex4ht.jar *
     ;
     mv tex4ht.jar /home/4/gurari/tex4ht.dir/texmf/tex4ht/bin/.
     ;
     cp /home/4/gurari/xtpipes.dir/xtpipes/lib/*
        /home/4/gurari/tex4ht.dir/texmf/tex4ht/xtpipes/.
"}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%
\section{Odd Ends}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%
\subsection{Font Decorations}
%%%%%%%%%%%%%

\<bold math\><<<

>>>

\<math bold templates\><<<
<xsl:template match="span[ @class = 'mathvariant-bold' ]" >
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:variable name="content">
       <xsl:apply-templates select="*" mode="content" />
    </xsl:variable>
    <xsl:choose>
       <xsl:when test="
          string-length( normalize-space( $content )) = 1
       " >

             <xsl:text> bold </xsl:text>

          <xsl:apply-templates select="*|text()|comment()" />
       </xsl:when>
       <xsl:otherwise>

             <xsl:text> begin bold </xsl:text>

          <xsl:apply-templates select="*|text()|comment()" />

             <xsl:text> end bold </xsl:text>

       </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>
</xsl:template>
>>>

%%%%%%%%%%%%%%%%%%
\section{Empty Elements}
%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%
\section{Prose}
%%%%%%%%%%%%%%%%%%


text:
\documentclass[12pt]{article}
\usepackage{amsmath}

\begin{document}

\title{WiggleTools - technical supplement}
\author{Daniel Zerbino}
\maketitle

\section{Online covariance calculation}

The following is a minor adaptation of a formula presented by David Will\'e, who came up with the idea.

The covariance between two series $X = \{x_n\}_{n=1..N}$ and $Y = \{y_n\}_{n=1..N}$ is defined as:
\begin{align}
cov(X,Y) &= E[(X-E[X])(Y-E[y])] \\
               &= E[XY] - E[X]E[Y]
\end{align}

When handling very large datasets, WiggleTools processes the data as soon as it is read then discards it, thus obviating the need for large memory machines. Equation (1) is a problem, because you can only know $E[X]$ and $E[Y]$ after going through the entire dataset, so all the data would have to be stored in memory to compute the overall expectation.

Equation (2) can be computed online. However, computing the sum of $(x_ny_n)_{n=1..N}$, then dividing by $N$ at the end of the run produces a very large number, which is prone to overflow the precision of the CPU given enough datapoints.

However, if we define $R_n = \sum_{i=1}^n x_iy_i$, $S_n^x =  \sum_{i=1}^n x_i$ and $S_n^y =  \sum_{i=1}^n y_i$, then we re-write equation (2):

$$cov(X,Y) = \frac{R_N-S_N^xS_N^y / N}{N}$$

We can therefore compute the covariance online, using the series $\{T^{xy}_n\}_{n=1..N} = \{R_n-S_n^xS_n^y / n\}_{i=1..N}$

$$cov(X,Y) = \frac{T^{xy}_N}{N}$$

Because it is a difference, $T^{xy}_n$ is less likely to overflow CPU precision than an online calculation of $R_n$.

We assume that we computed $T^{xy}_n$. Because of the nature of the data processed by WiggleTools, it is common to encounter series of points with identical values. We therefore assume that there exists $k \ge 1$ such that $(x_{n+1}=...=x_{n+k})$ and $(y_{n+1}=...=y_{n+k})$. This gives us:

\begin{align*}
T^{xy}_{n+k} &= R_{n+k} - \frac{S_{n+k}^xS_{n+k}^y}{n+k} \\
&= (R_n + kx_{n+1}y_{n+1}) - \frac{(S_n^x + kx_{n+1})(S_n^y+ky_{n+1})}{n+k} \\
&= R_n + kx_{n+1}y_{n+1} - \frac{S_n^xS_n^y + S_n^ykx_{n+1} + S_n^xky_{n+1} + k^2x_{n+1}y_{n+1}}{n+k} \\
&= R_n - \frac{S_n^xS_n^y}{n+k} + \left(1 - \frac{k}{n+k}\right)kx_{n+1}y_{n+1} - \frac{S_n^ykx_{n+1} + S_n^xky_{n+1}}{n+k}\\
&= R_n - S_n^xS_n^y\left(\frac{1}{n}-\frac{k}{n(n+k)}\right) +\frac{n}{n+k}kx_{n+1}y_{n+1} - \frac{S_n^ykx_{n+1} + S_n^xky_{n+1}}{n+k}\\
&= \left(R_n - S_n^xS_n^y/n\right) + \frac{k}{n(n+k)}S_n^xS_n^y +\frac{nk}{n+k}x_{n+1}y_{n+1} - \frac{k}{n+k}S_n^yx_{n+1} + S_n^xy_{n+1}\\
&= T^{xy}_n + \frac{k}{n+k}\left(\frac{S_n^xS_n^y}{n} +nx_{n+1}y_{n+1} - S_n^yx_{n+1} - S_n^xy_{n+1}\right)\\
\end{align*}

It is thus possible to compute $cov(X,Y)$ online, keeping only $S_n^x$, $S_n^y$, $T^{xy}_n$ and $n$ in memory. Note that if $n \gg k$, $S_n^x \gg x$ and $S_n^y \gg y$ we obtain:

$$T^{xy}_{n+k} - T^{xy}_n \approx \bar{x}\bar{y} +x_{n+1}y_{n+1} - \bar{y}x_{n+1} - \bar{x}y_{n+1} $$
$$T^{xy}_{n+k} - T^{xy}_n \approx (x_{n+1} - \bar{x})(y_{n+1} - \bar{y}) $$
This implies that although $T^{xy}_{n}$ grows in $\mathcal{O}(n)$, the increments are commensurate to the product of the standard deviations of $X$ and $Y$.

\section{Online variance computation}

The above formulas can easily be adjusted to computing variance of a series $X = \{x_n\}_{n=1..N}$, since:
$$\sigma^2(X)=cov(X,X)=\frac{T^{xx}_N}{N}$$

Where:
$$T^{xx}_0 = 0$$
and:
$$T^{xx}_{n+k} = T^{xx}_n + \frac{k}{n+k}\left(\frac{\left(S_n^x\right)^2}{n} +nx_{n+1}^2 - 2S_n^xx_{n+1}\right)$$

It is thus possible to compute $\sigma^2(X)$ online, keeping only $S_n^x$, $T^{xx}_n$ and $n$ in memory.

\section{Online Pearson correlation computation}

We apply the same idea to the Pearson correlation:

\begin{align*}
\rho &= \frac{cov(X,Y)}{\sqrt{\sigma^2(X)\sigma^2(Y)}} \\
\rho &= \frac{\frac{T^{xy}_N}{N}}{\sqrt{\frac{T^{xx}_N}{N}\frac{T^{yy}_N}{N}}} \\
\rho &= \frac{T^{xy}_N}{\sqrt{T^{xx}_NT^{yy}_N}}
\end{align*}

\end{document}

max_stars_repo_name: heavywatal/WiggleTools

max_issues_repo_name: heavywatal/WiggleTools

max_forks_repo_name: heavywatal/WiggleTools