\documentclass{article}

\usepackage{fancyhdr}
\usepackage{extramarks}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amsfonts}
\usepackage[plain]{algorithm}
\usepackage{algpseudocode}
\usepackage{matlab-prettifier}
\usepackage{graphicx}
\usepackage[export]{adjustbox}
%
% Basic Document Settings
%
\lstMakeShortInline[style=Matlab-editor]"

\topmargin=-1in
\evensidemargin=0in
\oddsidemargin=0in
\textwidth=6.5in
\textheight=9.0in
\headsep=0.25in

\linespread{1.1}

\rhead{\firstxmark}
\lfoot{\lastxmark}
\cfoot{\thepage}

\renewcommand\headrulewidth{0.4pt}
\renewcommand\footrulewidth{0.4pt}

%
% Homework Details
%   - Title
%   - Due date
%   - Class
%   - Section/Time
%   - Instructor
%   - Author
%

\newcommand{\hmwkTitle}{AMATH 482 Homework 1: An Ultrasound Problem}
\newcommand{\hmwkDueDate}{January 25, 2019}
\newcommand{\hmwkClassInstructor}{Professor Nathan Kutz}
\newcommand{\hmwkAuthorName}{\textbf{Skyler Hallinan}}

%
% Title Page
%

\title{
    \textmd{\textbf{\text{ } \hmwkTitle}}\\
}

\author{\hmwkAuthorName}
\date{}

\begin{document}
\maketitle

\section*{\fontsize{19}{15}\selectfont Abstract}
	We were given noisy, 3-D ultrasound data taken from our dog's intestine, in the hopes of identifying the path and location of a foreign object. We used the fast fourier transform to move our data to the frequency domain, and determined the frequency signature via averaging the spectrum. We centered a 3-D gaussian filter around these coordinates and multiplied it by the fourier-transformed data. We then transformed back into the space domain, and determined the location of the marble with our now denoised data.
\section*{\fontsize{19}{15}\selectfont Introduction and Overview}
	Our dog Fluffy has swallowed a marble that is currently in the small intestine, but we do not know the location or path of this foreign object. Through ultrasound taken at 20 time points, we have obtained data that show the spatial variations in our data. Due to our dog's movement, there is lots of noise in these measurements. We must determine the location of the marble at the 20th data point to know where to focus an intense acoustic wave and remove the marble. \\ \\
In order to remove noise from the data, we must apply a multidimensional fourier transform across the dataset, which consists of 20 64x64x64 sets of spacial ultrasound data. Then we must find the determine the frequency signature by taking the average of the fourier transforms at the 20 time points, which will remove the white noise, assuming it follows a normal distribution. This will let us  find our central frequency and the location in the frequency domain at which it occurs. We will then need to center a filter around this frequency, multiply it by our fourier-transformed dataset, then convert back into the time domain to denoise our data. With this now denoised spacial ultrasound data, we will be able to determine the location and path of the marble in Fluffy's intestine, and determine the 20th point so that we can remove the marble successfully.
\section*{\fontsize{19}{15}\selectfont Theoretical Background}
	Fourier introduced that a function $f(x)$ can be written as the sum of sines and cosines. This holds even if $f(x)$ is discontinuous:
	\begin{equation} \label{eq:1}
		f(x) = \frac{a_0}{2} + \sum_{n=1}^{\infty}(a_ncosnx + b_nsinnx) \quad x\in(-\pi,\pi]
	\end{equation}
	This expansion produces $2\pi$ periodic periodic functions because they are constructions of sines and cosines on the interval $(-\pi, \pi]$ \\ \\
	Expanding on this, we have the fourier transform. The fourier transform is an integral transform that decomposes a time defined function into its frequency components. We see that the Fourier transform and its inverse are defined as: \\
	\begin{equation} \label{eq:2a}
		F(k) = \frac{1}{\sqrt2\pi} \int_{-\infty}^{\infty} e^{-ikx} f(x) dx
	\end{equation}
		\begin{equation} \label{eq:2b}
		f(x) = \frac{1}{\sqrt2\pi} \int_{-\infty}^{\infty} e^{ikx} F(k) dk
	\end{equation}
	The fast fourier transform was developed by Cooley and Tukey in 1960 to perform the forward and inverse fourier transform at faster speeds with an operation count of $O(NlogN)$. It has fast speed and high accuracy, and the important detail to attaining this speed is discretizing the range $x \in [-L,L]$ into $2^n$ points. In addition, this algorithm shifts the data so that $x\in [0,L] \rightarrow [-L,0]$ and $x\in [-L,0] \rightarrow [0, L]$, multiplies every other mode by -1, and assumes that the user is working on a $2\pi$ periodic domain. In order to visualize this, one must  use "fftshift" on the data and the axes to undo the shifts naturally incurred by the fast fourier transform algorithm. In addition, multidimensional fast fourier transforms are possible.\\ \\
	Nontrivial noise when trying to detect things is a large issue in data that can be resolved through fourier shifting and filtering. Spectral filtering, where only a particular frequency of interest is chosen to be filtered on, allows for lots of unnecessary data and noise to be filtered out. We have the general gaussian filter for spectral filtering:
	\begin{equation} \label{eq:3}
	F(k) = exp(-\tau (k-k_0)^2)
	\end{equation}
	where $k$ is the wavenumber and $\tau$ is the bandwidth of the filter. Filters can be used to denoise the system by multiplying on data in the fourier domain, to remove unwanted signal. Then, after transformation back to the space domain, noise will be removed.
\section*{\fontsize{19}{15}\selectfont Algorithm Implementation and Development}
In order to conduct the fast fourier transform, we made sure to discretize our x into 64 points so that it matched the $2^n$ criteria. In addition, we rescaled our wavenumbers $k$ by $\frac{2\pi}{L}$ as the fast fourier transform assumes $2\pi$ periodic signals. We also created a grid by which to visualize the signals with "meshgrid" in both the space and frequency domain. \\ \\
We first reshaped the 20 x 262144 dataset into a 20x64x64x64 one using the "reshape" command. This 4-D array represented 20 different 64x64x64 3-D spatial representations through time. This data was noisy; as Figure 1 shows, there is almost no way to make anything out through all of the noise.  \\ \\
We then applied the n-dimensional fast fourier transform to our data via "fftn". This gave us a 4-D matrix: 20 rows of 64x64x64 fourier-transformed data. Next, we had to average the spectrum in order to remove the white noise from the data. We used a loop to add each of the 20 64x64x64 matrices together to an "avg" matrix, then normalized it by dividing "abs(avg)" by the max of the "abs(avg)". We graphed the "fftshift" of the "avg" matrix, then found the max value and index through the "[M,I] = max(avg)" command. After obtaining the integer index "I", we used "[i,j,l] = ind2sub([64,64,64], I)" to determine the appropriate indeces in "Ks" domain. We then plugged these indeces in to receive the appropriate coordinates; ie, "ks(l)" gave use the z coordinate in the frequency domain of the center frequency. We do note that we had to switch the "ks(i)" and "ks(j)" into the y and x coordinates respectively, due to quirks in MATLAB.  \\ \\
Finally, with the coordinates of the central frequency of the fftshifted fourier-transformed "avg" matrix, we created a 3-D gaussian filter centered around that point, choosing a specific $\tau$ value. We ifftshifted this gaussian filter (as we generated it in the fftshifted domain), multiplied our 4-D matrix by it, then used "ifftn" to convert this whole 4-D, 20x64x64x64 matrix back into the space domain. After this, we determined the max coordinate of each of the 20 64x64x64 denoised spacial datsets (which represented the point of the marble at that time point) and used "isosurface" and "plot3" to visualize the marble through time.

\begin{figure}[H]
\begin{center}
\includegraphics[width = 8cm]{sample3d}
\includegraphics[width = 8cm]{fourieravg}
\caption{\label{fig:scaled_diss} (left) 3-D isosurface plot in space of the ultrasound at the 20th time point. Isovalue of 0.75.}
\caption{\label{fig:scaled_diss} (right) 3-D isosurface plot in frequency domain of normalized, averaged fourier-transformed data. Isovalue of 0.725.}
\end{center}
\end{figure}

\section*{\fontsize{19}{15}\selectfont Computational Results}
	After summing each of the 20 fourier-transformed 64x64x64 matrices into an "avg" matrix and normalizing, we plotted the "fftshift" of this on the frequency domain. Figure 2, shows our normalized fourier-transformed average data, and there appears to be a clear central frequency, taking the form of the blob in the figure. We determined the coordinates of this central frequency, to be at the coordinate $(1.8550, -0.8378, 0)$ on the Kx, Ky, Kz grid. \\ \\
We then centered our 3-D gaussian filter around this coordinate, and generated the following 3-D gaussian filter: "exp(fwid*(Kx - cx).^2 +fwid*(Ky - cy).^2 + fwid*(Kz - cz).^2)" where "cx", "cy", and "cz" are 1.8850, -0.3878, and 0, and where our $\tau$ value in the general gaussian filter equation was "fwid = -0.5" (we used a negative here for simplicity in multiplication. $\tau$ is usually positive). We tried a variety of $\tau$ values, and found that there was generally a large range that worked (0.1 to 2); however, at too small $\tau$ values, there still appeared to be lots of noise in the data, and at $\tau$ values to high, our isosurface graph and 3-D plot in time graphs became unreadable. \\ \\
After multiplying the "ifftn" of this filter to each of the 20 fourier-transformed 64x64x64 data, we took the ifftn of the entire 4-D dataset, and plotted it with "isosurface". We obtained Figure 3, which shows a clear path and shape of the marble through time, as the data is now denoised. In addition, we generated Figure 4, which shows the path of the marble in the form of a line graph. Through these we determined that the 20th point, the marble was at location $(-5.1563, 4.2188, -6.0938)$.

\begin{figure}[H]
\begin{center}
\includegraphics[width = 8cm]{denoised3d}
\includegraphics[width = 8cm]{marblepath}
\caption{\label{fig:scaled_diss} (left) 3-D isosurface plot in space of the denoised marble. Isovalue of 0.6.}
\caption{\label{fig:scaled_diss} (right) 3-D plot in space domain of marble path.}
\end{center}
\end{figure}

\section*{\fontsize{19}{15}\selectfont Summary and Conclusions}
We started with noisy spatial ultrasound data through time and were trying to determine the location of a marble in our dog's intestine. We located the coordinates of the central frequency at $(1.8550, -0.8378, 0)$ via averaging the spectrum of 20 64x64x64 fourier-transformed datasets. We then generated a filter with a $\tau$ value of 0.5 that we shifted and multiplied by the fourier-transformed 4-D matrix. With this denoised data, we were able to locate the marble in our dog's intestine at $(-5.1563, 4.2188, -6.0938)$ . Based on our results, we suggest to focus the intense acoustic wave at the location of $(-5.1563, 4.2188, -6.0938)$ (in the x, y, z space domain) in order to remove the marble and save Fluffy.
\pagebreak

\section*{\fontsize{19}{15}\selectfont Appendix A}
\subsection*{MATLAB functions used and implementation}
"abs(X)" : Returns the absolute value of every element in X, or complex magnitude if the element is complex. We used this function to normalize the data by dividing "abs(X)" with the max of "abs(X(:))", where X was a 64x64x64 matrix. \\ \\
"[i,j,k] = ind2sub(siz,IND)" : Given a index "IND", it returns the "i", "j", and "k" indeces, which can then be translated into spacial or frequency domain coordinates. We used this command to find the center frequency of our averaged spectrum, and the location of the marble throughout time in the space domain via our denoised data. \\ \\
"fftn(X)" : Performs a multidimensional fast fourier transform on "X", an N-D array. We used this fourier transform on our 20x64x64x64 ultrasound data to transform into the frequency domain. \\ \\
"fftshift(X)" : Rearranges the contents of "X" by placing the zero-frequency component to the center of the array. If "X" is a vector, shifts the left and right halves of "X", while if "X" is a matrix, the $I$ and $III$ quadrants are switched, as well as the $II$ and $IV$ quadrants. We used this to change our transformed data and our axes for proper visualization, with "isosurface" and such.  \\ \\
"ifftn(X)" : Performs a multidimensional discrete inverse fast fourier transform on "X". We used this after multiplying our centralized filter on the fourier-transformed data to transform it back into the spacial domain as denoised data.\\ \\
"ifftshift(X)" : Performs the inverse of "fftshift(X)". We used this on our filter to undo the "fftshift" that had been done when creating the filter. \\ \\
"isosurface(X,Y,Z,V,isovalue)" : Computes and plots the isosurface from volume data "V" at the isosurface value "isovalue". We used this to visualize the ultrasounds at different times in the spatial and frequency domain.\\ \\
"linspace(x1,x2,n)" : Creates a vector of "n" evenly spaced points from "x1" to "x2". We used this to create a linearly spaced vector in the spacial domain, which we then used for the "meshgrid".  \\ \\
"[X,Y,Z] = meshgrid(x,y,z)" : Creates 3-D grid coordinates defined by the "X", "Y", and "Z" vectors. We used this to define axes to plot isosurfaces in the space and frequency domains.\\ \\
"max(A)" : If "A" is a vector, then it returns the maximum value of this vector. We used this for normalization of data. \\ \\
"[M,I] = max(A)" : Returns the maximum value "M" and the index "I"  of the matrix, which we then used in "ind2sub" to find direct coordinates.  \\ \\
"plot3(X1,Y1,Z1)" : Displays a 3-dimensional plot of a set of datapoints through inputs "X1", "Y1", "Z1". We used this to visualize the path of the marble in the intestine after noise was removed and 20 data points were obtained in 3-dimensional space. \\ \\
"reshape(A,sz)" : Reshapes the array "A" to the size defined by "sz". We used this to store the initial data as a 4-D 20x64x64x64 matrix. We also used this command to access each row of this 4-D matrix for plotting, etc. \\ \\
"zeros(A,B,C)" : Creates a matrix filled with zeros of size "A x B x C". We used this to initialize an average matrix, where we stored and added 20 64x64x64 fourier transformed matrices together. \\ \\

\section*{\fontsize{19}{15}\selectfont Appendix B}
\subsection*{MATLAB code}
\begin{lstlisting}[style=Matlab-editor]
clear all; close all; clc;
load Testdata

L=15; % spatial domain
n=64; % Fourier modes

x2=linspace(-L,L,n+1); x=x2(1:n); y=x; z=x;
k=(2*pi/(2*L))*[0:(n/2-1) -n/2:-1]; ks=fftshift(k);
[X,Y,Z]=meshgrid(x,y,z);
[Kx,Ky,Kz]=meshgrid(ks,ks,ks);

figure
Un(:,:,:)=reshape(Undata(20,:),n,n,n);
isosurface(X,Y,Z,abs(Un), 0.75)
axis([-20 20 -20 20 -20 20]), grid on, drawnow
xlabel("x"), ylabel("y"), zlabel("z")
title("Ultrasound in 3-D space (20th measurement)")

Undatashape = reshape(Undata, [20,n,n,n]);
Ut= fftn(Undatashape);
avg = zeros(64,64,64);
for p = 1:20
    avg(:,:,:) = avg + abs(reshape(Ut(p,:),n,n,n));
end
avg = avg./20;
avg = abs(avg)/max(abs(avg(:)));

figure
isosurface(Kx,Ky,Kz,fftshift(avg), 0.725)
axis([-10 10 -10 10 -10 10]), grid on, drawnow
xlabel("Kx"), ylabel("Ky"), zlabel("Kz")
title("Normalized Sum of Fourier Transformed Ultrasound Data")

avgshift = fftshift(avg);
[maximum, index] = max(avgshift(:));

[ii,jj,ll] = ind2sub([n,n,n], index);

cx = ks(jj); cy = ks(ii); cz = ks(ll);
%%
fwid = -0.01;
filter = exp(fwid*(Kx - cx).^2 +fwid*(Ky - cy).^2 + fwid*(Kz - cz).^2);

for j=1:20
    Uncur(:,:,:)= reshape(Ut(j,:),n,n,n);
    filterall(j,:,:,:) = ifftshift(filter).*Uncur;
    close all, isosurface(Kx,Ky,Kz,abs(fftshift(Utfn)), 0.5)
    axis([-20 20 -20 20 -20 20]), grid on, drawnow
end

figure;
Undenoise = ifftn(filterall);
for j = 1:20
    Unslice(:,:,:)= reshape(Undenoise(j,:),n,n,n);
    Unslice = abs(Unslice)/max(abs(Unslice(:)));
    [maximum, index] = max(abs(Unslice(:)));
    [ii,jj,ll] = ind2sub([n,n,n], index);
    plotdata(j,:) = [X(ii,jj,ll),Y(ii,jj,ll),Z(ii,jj,ll)];
    isosurface(X,Y,Z,abs(Unslice), 0.6)
    axis([-20 20 -20 20 -20 20]), grid on, drawnow
end
xlabel("x"), ylabel("y"), zlabel("z")
title("Denoised Ultrasounds in Space");

figure;
plot3(plotdata(:,1), plotdata(:,2), plotdata(:,3), "Linewidth", 1.5)
axis([-15 15 -10 10 -15 15]), grid on, drawnow
xlabel("x"), ylabel("y"), zlabel("z")
title("Marble Path in Space");

point = plotdata(20,:)
\end{lstlisting}

\end{document}


\documentclass{article}
%include polycode.fmt
%
% %s/{lattice-\(.*\)}/{..\/images\/lattice-\1.png}/
% %s/{cat-\(.*\)}/{..\/images\/cat-\1.png}/
%
\begin{document}
This post contains excerpts from \href{https://oleg.fi/pdfs/Monotone.pdf}{a PDF "post" I have written}.
It looks way better in PDF.

\emph{Partial ordered set}, or poset for short is well used example in
category theory books.
Yet, posets are not too familiar for an average
CT-curious Haskeller, yet they are easy to visualise!
Let's do exactly that, and mention elementery bits of category theory.
In particular, I'll scan over the six first chapters of
\emph{Category Theory} by Steve Awodey,
repeating related definitions and poset examples.\footnote{%
If you want to learn category theory, getting a book is a small investment.
Your public or university library probably have a copy.
}

\section{Categories}
\label{sec:categories}

\begin{definition}[Awodey 1.1]\textbf{Definition} (Awodey 1.1)
A \emph{category} consist of the following data
\begin{itemize}
\item Objects: $A, B, C, \ldots$
\item Arrows: $f, g, h, \ldots$

\item For each arrow $f$, there are given objects

\begin{equation*}
\mathrm{dom}(f), \qquad \mathrm{cod}(f)
\end{equation*}

called the \emph{domain} and \emph{codomain} of $f$. We write

\begin{equation*}
f : A \to B
\end{equation*}

to indicate that $A = \mathrm{dom}(f)$ and $B = \mathrm{cod}(f)$.

\item Given arrows $f : A \to B$ and $g : B \to C$, that is, with

\begin{equation*}
\mathrm{cod}(f) = \mathrm{dom}(g)
\end{equation*}

there is given an arrow

\begin{equation*}
g \circ f : A \to C
\end{equation*}

called the \emph{composite} of $f$ and $g$.

\item For each object $A$, there is given an arrow

\begin{equation*}
1_A : A \to A
\end{equation*}

called the \emph{identity arrow} of $A$.

\item Associativity:

\begin{equation*}
h \circ (g \circ f) = (h \circ g) \circ f
\end{equation*}

for all $f : A \to B$, $g : B \to C$, $h : C \to D$.

\item Unit:

\begin{equation*}
f \circ 1_A = f = 1_B \circ f
\end{equation*}

for all $f : A \to B$.
\end{itemize}
\end{definition}

We'll see how |Category| type-class is related later, in later section.

\rule{\textwidth}{1pt}
\ldots
\rule{\textwidth}{1pt}

\section{Functor}

Before proceeding, we'll answer a question: is there a category
with posets as objects? Yes, it's called $\mathbf{Pos}$!
What are the arrows in this category?
An arrow from a poset $A$ to a poset $B$ is a function

\begin{equation*}
m : A \to B
\end{equation*}

that is \emph{monotone}, in the sense that, for all $a, a' \in A$,

\begin{equation*}
a \le_A a' \qquad\text{implies}\qquad m(a) \le_B m(a').
\end{equation*}

We need to know that $1_A : A \to A$ is monotone, and also
that if $f : A \to B$ and $g : B \to C$ are monotone, then $g \circ f : A \to C$
is monotone. That holds, check!

Recall, posets are categories, so monotone functions are "mappings" between
categories. A "homomorphism\footnote{morphism preserving the structure} of categories"
is called a functor.

\begin{definition}[Awodey 1.2]\textbf{Definition} (Awodey 1.2)
A \emph{functor}

\begin{equation*}
F : \mathbf{C} \to \mathbf{D}
\end{equation*}

between categories $\mathbf{C}$ and $\mathbf{D}$ is a mapping of objects
to objects and arrows to arrows, in such a way that
\begin{itemize}
\item $F (f : A \to B) = F(f) : F(A) \to F(B)$,
\item $F(1_A) = 1_{F(A)}$,
\item $F(g \circ f) = F(g) \circ F(f)$.
\end{itemize}
That is, $F$ preserves domains and codomains, identity arrows,
and composition. A functor $F : \mathbf{C} \to \mathbf{D}$ thus gives
a sort of "picture" -- perhaps distorted -- of $\mathbf{C}$ in $\mathbf{D}$.
\end{definition}

The \Haskell\ version looks quite different:
\begin{code}
class Functor f where
  fmap :: (a -> b) -> f a -> f b
\end{code}
There is a mismatch of a notation of category theory, and what
can be written as code. In CT notation $F$ acts both on objects and arrows.
In \Haskell\ |f| acts on objects, and |fmap f| acts on arrows.
Substituting above, |id| and |.| into definition of functor, will
also give familiar laws
\begin{code}
fmap id       = id
fmap (g . f)  = fmap g . fmap f
\end{code}

However, \Haskell\ |Functor|-class is only for functors from a pseudo-category $\mathbf{Hask}$
to itself, where |f|, a mapping from types to types is a type-constructor,
not arbitrary type family.
|Functor| is a very special case of category theoretical variant.

With small posets, like |Bool| and |M2| we can visualise a
monotone function, a functor. Let's consider a function
\begin{code}
f :: Bool -> M2
f True   = M2i
f False  = M2o
\end{code}

\begin{figure}[ht]
\begin{center}
\includegraphics[scale=0.33]{../images/cat-bool-m2.png}
\end{center}
\caption{Graph of |f :: Bool -> M2|}
\label{fig:f-bool-to-m2}
\end{figure}

The graph of |f| is on \cref{fig:f-bool-to-m2}. Dotted and dashed lines are arrows
in |Bool| and |M2| respectively.
We can see on figure, that |f| indeed gives a picture of |Bool| in |M2|.

In \Haskell\ we have only written
a mapping of objects, |True| and |False|. The mapping of arrows is something
we need to check, to be able to claim that |f| is a functor, and therefore
a monotone function. The other way around, there are mappings from
|Bool| to |M2| which aren't monotone, and aren't functors.

In this section we went backwards. More principal approach would been to first
consider functors between poset categories. The monotonicity requirement is
implied by first functor requirement. This is a power of category
theory. When you look for something, category theory tells you which
properties it should have. Once you find something which satisfies
the requirements, you know that it's the right one (up to an isomorphism).

\rule{\textwidth}{1pt}
\ldots
\rule{\textwidth}{1pt}

Exponential lattices with |M2| are pretty. |ZHO -> M2| (\cref{fig:zho2m2})
has nice planar graph. \ldtos . Yet the final stress test is
|(ZHO -> ZHO) -> ZHO|, or $\mathtt{ZHO}^{\mathtt{ZHO}^\mathtt{ZHO}}$ is on \cref{fig:big}.
A beautiful monster.

\begin{figure}[ht]
\begin{center}
\includegraphics[scale=0.3]{../images/lattice-zho2m2.png}
\end{center}
\caption{|ZHO -> M2| lattice}
\label{fig:zho2m2}
\end{figure}

\begin{figure}[ht]
\begin{center}
\includegraphics[scale=0.15]{../images/lattice-big.png}
\end{center}
\caption{|(ZHO -> ZHO) -> ZHO| lattice}
\label{fig:big}
\end{figure}

\end{document}


\section{Computational Platforms and Software Libraries}
This section describes technical details about the implementation of the solutions exposed in this document. It also contains
the collected data used for the analysis.

The results of each run are tested with 16bit Fletcher's checksum so that errors can be quickly checked over large matrices \cite{fletcher}.
\subsection{Serial implementation}
The \emph{sequential} version of the FW algorithm can be found \href{https://github.com/firaja/Parallel-FloydWarshall/blob/master/sequential.c}{here}.
The program compiles as follows:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ gcc sequential.c -o sequential.out -O3
\end{lstlisting}

notice the \texttt{-O3} flag that makes the program run $3.5$ times faster.
The program accepts 2 arguments:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ ./sequential.out <v> <d>
\end{lstlisting}
where \texttt{v} is the number of verteces, expressed as positive integer, and \texttt{d} is the density of the presence of edges, expressed as an integer from 0 to 100.
\par
The \texttt{gcc} version used for this work is 7.5.0 and the program ran on a Intel Core i7-9700K. \\
\textbf{Table \ref*{tab:seq-time}} shows the execution time (expressed in milliseconds) depending on the number of vertices.

\begin{table}[h!]
\centering
\begin{tabular}{|r|r|}
\hline
\rowcolor[HTML]{3166FF}
{\color[HTML]{FFFFFF} \textbf{Vertices}} & {\color[HTML]{FFFFFF} \textbf{Execution time}} \\ \hline
1000                                     & 1095 ms                                        \\ \hline
2000                                     & 8860 ms                                        \\ \hline
5000                                     & 138643 ms                                      \\ \hline
7500                                     & 468750 ms                                      \\ \hline
10000                                    & 1112111 ms                                     \\ \hline
12500                                    & 2170138 ms                                     \\ \hline
\end{tabular}
\caption{Execution time of the \emph{serial} FW}
\label{tab:seq-time}
\end{table}

\textbf{Figure \ref*{fig:seq-time}} shows the trend of the execution time.

\begin{figure}[h!]
\centering
\includegraphics[width=3.5in]{images/seq-time}
\captionsetup{justification=centering,margin=2cm}
\caption{Trend of the execution time based on Table \ref*{tab:seq-time}}
\label{fig:seq-time}
\end{figure}

It is easy to notice that the graph represents a
third grade curve; this is the interpolated function starting from the collected data:
\[f(n) = 2.22n^3 - 18.83n^2 + 92.14n -94.84 \in \Theta(n^3) \]

\subsection{MPI implementation}\label{mpiimpl}

The \emph{MPI} version of the FW algorithm can be found \href{https://github.com/firaja/Parallel-FloydWarshall/blob/master/mpi.c}{here}.
The program compiles as it follows:

\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ mpicc -g -Wall mpi.c -o mpi.out -O3
\end{lstlisting}
Like the \emph{serial} version, the program accepts 2 arguments + 1 for $\texttt{mpirun}$:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ mpirun -np <p> mpi.out <v> <d>
\end{lstlisting}
The \texttt{MPI} version used for this work is 2.1.1 and the program ran on a cluster of 8 nodes over a LAN. \\
\textbf{Table \ref*{tab:mpi-time}} shows the execution time (expressed in milliseconds) and the percentage of time spent in initialization and communication, depending on the number of processors;
in this case the program computed the \emph{APSP} problem for 5040 vertices.

\begin{table}[h!]
\centering
\begin{tabular}{|r|r|r|}
\hline
\rowcolor[HTML]{F56B00}
{\color[HTML]{FFFFFF} \textbf{Processors}} & {\color[HTML]{FFFFFF} \textbf{Execution time}} & {\color[HTML]{FFFFFF} \textbf{MPI \%}} \\ \hline
1                                          & 145447 ms                                               & 0.06                                 \\ \hline
2                                          & 75059 ms                                               & 2.57                                 \\ \hline
3                                          & 52336 ms                                               & 4.45                                \\ \hline
4                                          & 39962 ms                                               & 5.47                                \\ \hline
5                                          & 33184 ms                                               & 6.95                                 \\ \hline
6                                          & 28731 ms                                               & 8.35                                \\ \hline
7                                          & 25853 ms                                               & 9.50                                 \\ \hline
8                                          & 23120 ms                                               & 11.00                                \\ \hline
\end{tabular}
\caption{Execution time of the \emph{MPI} FW}
\label{tab:mpi-time}
\end{table}
Timings are captured through \texttt{mpiP} that calculates the percentage of time spent by MPI for initialization/finalization and communication.
\texttt{mpiP} is a lightweight profiling library for MPI applications. Because it only collects statistical information about MPI functions, \texttt{mpiP} generates considerably less overhead and much less data than a tracing tools. All the information captured by \texttt{mpiP} is task-local. It only uses communication during report generation, typically at the end of the experiment, to merge results from all of the tasks into one output file.

\subsection{OpenMP implementation}\label{ompimpl}
The \emph{OpenMP} version of the FW algorithm can be found \href{https://github.com/firaja/Parallel-FloydWarshall/blob/master/openmp.c}{here}.
The program compiles as it follows:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ g++ -fopenmp openmp.c -o openmp.out -O3
\end{lstlisting}
Unlike the \emph{serial} version, the program accepts 3 arguments:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ ./openmp.out <v> <d> <t>
\end{lstlisting}
where \texttt{t} is the number of threads OpenMP can use for parallelization. \\
The \texttt{gcc} version used for this work is 7.5.0 and the program ran on a Intel Core i7-9700K, which has 8 core with no Hyper-Threading.
\textbf{Table \ref*{tab:omp-time}} shows the execution time (expressed in milliseconds) depending on the number of vertices and available cores.

\begin{table}[h!]
\centering
\begin{tabular}{|r|r|r|r|}
\hline
\rowcolor[HTML]{CB0000}
\multicolumn{1}{|c|}{\cellcolor[HTML]{CB0000}{\color[HTML]{FFFFFF} \textbf{Vertices}}} & \multicolumn{1}{c|}{\cellcolor[HTML]{CB0000}{\color[HTML]{FFFFFF} \textbf{2 threads}}} & \multicolumn{1}{c|}{\cellcolor[HTML]{CB0000}{\color[HTML]{FFFFFF} \textbf{4 threads}}} & \multicolumn{1}{c|}{\cellcolor[HTML]{CB0000}{\color[HTML]{FFFFFF} \textbf{8 threads}}} \\ \hline
1000                                                                                & 541 ms                                                                                & 364 ms                                                                                & 158 ms                                                                                \\ \hline
2000                                                                                & 4365 ms                                                                                & 2921 ms                                                                                & 1260 ms                                                                                \\ \hline
5000                                                                                & 69590 ms                                                                                & 46443 ms                                                                                & 19496 ms                                                                                \\ \hline
7500                                                                                & 230260 ms                                                                                & 155531 ms                                                                                & 65118 ms                                                                                \\ \hline
10000                                                                                & 543900 ms                                                                                & 367434 ms                                                                                & 153682 ms                                                                                \\ \hline
12500                                                                                & 1063129 ms                                                                                & 716363 ms                                                                                & 299006 ms                                                                                \\ \hline
\end{tabular}
\caption{Execution time of the \emph{OpenMP} FW}
\label{tab:omp-time}
\end{table}

\subsection{CUDA implementation}\label{cudaimpl}
The \emph{CUDA} version of the FW algorithm can be found \href{https://github.com/firaja/Parallel-FloydWarshall/blob/master/cuda.cu}{here} (pre-Volta architecture). Alternatively the version
that uses only global memory is \href{https://github.com/firaja/Parallel-FloydWarshall/blob/master/cuda2.cu}{here} (Volta and post-Volta architectures).
The program compiles as follows:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ nvcc cuda.cu -o cuda.out \
  -gencode=arch=compute_75,code=compute_75 -O3
\end{lstlisting}
Unlike the \emph{serial} version, the program accepts 3 arguments:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ ./cuda.out <v> <d> <b>
\end{lstlisting}
where \texttt{b} is the number of threads per block. \\
The \texttt{nvcc} version used for this work is 10.2 and the program ran on a CPU Intel Core i7-9700K and a GPU NVIDIA GeForce RTX 2070 Super.
Table \ref*{tab:cuda-time} shows the execution time (expressed in milliseconds) depending on the number of vertices and the block size of threads.

\begin{table}[h!]
\centering
\begin{tabular}{|r|r|r|r|}
\hline
\rowcolor[HTML]{009901}
\multicolumn{1}{|l|}{\cellcolor[HTML]{009901}{\color[HTML]{FFFFFF} \textbf{verteces}}} & \multicolumn{1}{l|}{\cellcolor[HTML]{009901}{\color[HTML]{FFFFFF} \textbf{1024 block}}} & {\color[HTML]{FFFFFF} \textbf{256 block}} & \multicolumn{1}{l|}{\cellcolor[HTML]{009901}{\color[HTML]{FFFFFF} \textbf{32 block}}} \\ \hline
1000                                                                                & 24 ms                                                                                & 19 ms                                                  & 53 ms                                                                                \\ \hline
2000                                                                                & 219 ms                                                                                & 186 ms                                                 & 356 ms                                                                                \\ \hline
5000                                                                                & 2818 ms                                                                                & 2709 ms                                                & 4966 ms                                                                                \\ \hline
7500                                                                                & 9894 ms                                                                                & 9044 ms                                                & 16297 ms                                                                                \\ \hline
10000                                                                                & 22190 ms                                                                                & 21392 ms                                               & 38208 ms                                                                                \\ \hline
125000                                                                                & 42955 ms                                                                                & 41460 ms                                               & 75034 ms                                                                                \\ \hline
\end{tabular}
\caption{Execution time of the \emph{CUDA} FW}
\label{tab:cuda-time}
\end{table}

Using a CPU-based timer would measure only the kernel's launch time and not the kernel's execution time and it would require a host-device synchronization point, like \texttt{cudaDeviceSynchronize()} which stalls the GPU pipeline.

So timings are taken with CUDA events that are created and destroyed with \texttt{cudaEventCreate()} and \texttt{cudaEventDestroy()}. \texttt{cudaEventRecord()} places the start and stop events into the default stream  and the device will record a time stamp for the event when it reaches that event in the stream.
The \texttt{cudaEventElapsedTime()} function returns in the first argument the number of milliseconds time elapsed between the recording events. This value has a resolution of approximately one half microsecond.

\subsection{Hybrid implementation}\label{hybimpl}
The \emph{MPI + OpenMP} version can be found \href{https://github.com/firaja/Parallel-FloydWarshall/blob/master/hybrid.c}{here}.
The program compiles as follows:
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ mpicc -g -fopenmp hybrid.c -o hybrid.out -O3
\end{lstlisting}
The program accepts 4 arguments (see $MPI$ and $openMP$ versions):
\begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
$ mpirun -np <p> hybrid.out <n> <d> <t>
\end{lstlisting}


\documentclass{amsart}
\usepackage{amsmath}
\usepackage{amsthm}
%\usepackage{a4wide}
%\usepackage{enumerate}

\newcommand{\R}{\mathbb{R}}
\newcommand{\Z}{\mathbb{Z}}
\DeclareMathOperator{\Spa}{Spa}
\DeclareMathOperator{\Spv}{Spv}
\DeclareMathOperator{\pre}{pre}

\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{proposition}[theorem]{Proposition}
\theoremstyle{remark}
\newtheorem{remark}[theorem]{Remark}
\newtheorem*{remarkn}{Remark}

\begin{document}

\title{Adic spaces.}

\section{$\mathcal{V}^{\pre}$}

The definition of an adic space is on Wedhorn p80. The category $\mathcal{V}$ is defined on p80 and the category $\mathcal{V}^{\pre}$ is defined on p76.

The category $\mathcal{V}^{\pre}$ is defined as follows. An object is a topological space, plus a presheaf of complete topological rings, such that the stalks (direct limit in the category of rings, with no topology) are local, and also each stalk is equipped with an equivalence class of valuations such that the support of the valuation is the maximal ideal. We know that supports are constant across equivalence classes so there is no obstruction to making this definition in Lean.

Oh wait -- do we have direct limits of rings? I think there was some hold-up getting them into mathlib.

TODO : direct limits of commutative rings (just for a directed set)

A morphism in $\mathcal{V}^{\pre}$ is a continuous map $f:X\to Y$ plus a morphism $f^\flat:\mathcal{O}_Y\to f_*\mathcal{O}_X$ of presheaves, such that the induced map $f^\flat_x:\mathcal{O}_{Y,f(x)}\to\mathcal{O}_{X,x}$ has the property that the valuation on the stalk at $x$ pulls back (up to equivalence) to the valuation on $f(x)$.

TODO : universal property of direct limits

TODO : pushforward of presheaf (NB : this is the easy one).

TODO : composition of morphisms is a morphism, identity morphism is a morphism, definition of isomorphism.

If $X$ + structure is an object in $\mathcal{V}^{\pre}$ and $U$ is an open subset of $X$ (or more generally I think we should let $U\to X$ be an open immersion) then the pullback of everything to $U$ should be an object in $\mathcal{V}^{\pre}$ too.

TODO : define this construction. tedious check that stalks don't change etc.

The category $\mathcal{V}$ is just the full subcategory of $\mathcal{V}^{\pre}$ consisting of objects for which the presheaf is a sheaf.

TODO : definition of sheaf.

\section{$\Spa(A)$}

Last time I checked, we had a sorry-free definition of a Huber Pair $A=(R,R^+)$. If $A$ is a Huber pair, then it would be nice to construct an object of $\mathcal{V}^{\pre}$ associated to this data. However, this is annoyingly difficult because there is a bunch of API for Cont (theorem 3.3 of Huber's paper ``continuous valuations'') which I propose skipping. Here are the details.

We have a topological space structure on $\Spv(R)$, the set of all valuations on $R$, and $\Spa(A)$ is the subspace of continuous valuations which are bounded by 1 on $R^+$. We already have this. The topology is generated by basic opens (which we have), and rational opens are open (we have this).

TODO : rational opens are a basis [NB : do we use this?]

Now let's talk about the presheaf. First we need some ring constructions. If $s\in R$ and $T\subseteq R$ is a finite subset generating an open ideal in $R$, then there is a rational open subset of $\Spa(R)$ which Wedhorn calls $R(T/s)$, but following general alg geom conventions let me call it $D(T/s)$ instead. The idea is that the value of the presheaf on $D(T/s)$ is a ring called $R\langle T/s\rangle$ and then we extend the presheaf to a general open by taking projective limits.

TODO : Johan is in the process of defining $R(T/s)$ and proving that it is a Huber ring. We also need that it's an $R$-algebra.

TODO : Prove the unversal property of $R(T/s)$ as in Wedhorn 5.51

TODO : Define $R\langle T/s\rangle$ to be the completion of this ring. I believe Patrick has pushed enough of ring closures to be able to do this. We also need that it's an $R$-algebra, which just boils down to having a map from a ring to its completion.

TODO : Prove the universal property of $R\langle T/s\rangle$ as descrived on Wedhorn p74 just before Lemma 8.1 -- this should just follow from the universal property of completion and the universal property of $R(T/s)$.

Johan has defined {\tt rational\_open (s : A) (T : set A)} to be $D(T/s)$.

Note that $D(T/s)=D(T\cup\{s\}/s)$ so WLOG $s\in T$, and if $s_1\in T_1$ and $s_2\in T_2$ then Johan has proved that $D(T_1/s_1)\cap D(T_2/s_2)=D(T_1T_2/s_1s_2)$. There is also a map $A\langle T_1/s_1\rangle \to A\langle T_1T_2/s_1s_2\rangle$, which follows immediately from the universal property for completion.

Note: it is true that if $D(T_1/s_1)\subseteq D(T_2/s_2)$ then there's a natural map $A\langle T_2/s_2\rangle \to A\langle T_1/s_1\rangle$. However, to deduce this from the universal property is quite a substantial amount of work, as far as I can see, because it relies on Wedhorn 7.52 which relies on Wedhorn 7.18 which relies on Huber's Continuous valuations paper and also a bunch of stuff about specialising and generalising valuations.

However, we can still define the presheaf! We would like to define its value on an open $U\subseteq\Spa(A)$ to be the projective limit of the $R\langle T/s\rangle$ as $(T,s)$ range over the pairs with the usual property ($T$ is finite and generates an open ideal) with $D(T/s)\subseteq U$. The problem is with the transition maps; if $a_1\in D(T_1/s_1)$ and $a_2\in D(T_2/s_2)$ and if $D(T_2/s_2)\subseteq D(T_1/s_1)$ then we want to say that $a_1$ gets mapped to $a_2$ when we apply the map $R\langle T_1/s_1\rangle\to R\langle T_2/s_2\rangle$ which we can't construct. However we can use the following trick. WLOG $s_i\in T_i$. Then we can construct the maps $R\langle T_1/s_1\rangle\to R\langle T_1T_2/s_1s_2\rangle$ and $R\langle T_2/s_2\rangle\to R\langle T_1T_2/s_1s_2\rangle$ from the universal property. This latter map is known to be an isomorphism, even though we can't prove it. However it does mean that if we demand that $a_1$ and $a_2$ have the same image in $R\langle T_1T_2/s_1s_2\rangle$ for all $(T_i,s_i)$ then the corresponding subset of the product will be provably (in maths) the projective limit and hence the correct object.

My proposal for the definition of the value of the presheaf on an open $U$ is hence the subset of $\prod_{(T,s)\,:\,D(T/s)\subseteq U}R\langle T/s\rangle$ consisting of elements $a_{(T,s)}$ such that $a_{(T_1,s_1)}$ and $a_{(T_2,s_2)}$ agree in $R\langle T_1T_2/s_1s_2\rangle$. It's a theorem of maths that this is (canonically) isomorphic to the value of the correct presheaf on $U$.

TODO : Check that this closed (because $R\langle T/s\rangle$ is Hausdorff) subring of an arbitrary product of complete topological rings is complete (ask Patrick!). Is this something to do with reflective subcategories?

Note that this is trivially checked to be a presheaf.

TODO : check it's a presheaf.

Now we need to put a valuation on the stalks. The way this works is that if $v$ is a continuous valuation on $R$ then there's a map $R\to K_v$ and a valuation on $K_v$ extending $v$. Now say $(T,s)$ are as usual with $v\in D(T/s)$; then $v(s)$ is non-zero so $s\in K_v^\times$, and for $t\in T$ we have $v(t)\leq v(s)$, so $t/s\in K_v$ has valuation at most~1. By the universal property of $R(T/s)$, we get a map $R(T/s)\to K_v$ and hence a valuation on $R(T/s)$. We will also need to prove a uniqueness statement to make sure that the valuations glue. Note that the valuation group doesn't go up. This still needs some thought.

TODO : There's a lemma here, which we need to prove. A continuous valuation on $R$ extends uniquely to a continuous valuation on its completion! I haven't thought about this and it's essential. Huber says it's ``clear''.{\bf Note that this needs to be checked -- the proof in Wedhorn uses a lot of machinery which we don't have and proves something much stronger.}

TODO : valuation on the factors gives a valuation on the direct limit.

Now to prove that this is an object in $\mathcal{V}^{\pre}$ we would need to prove that stalks are local and that the support of the valuation is the maximal ideal. This is true in maths but I propose skipping the Lean proofs because they I think will involve Huber 3.3. However we do not need these proofs -- we are just making a definition.

\section{Adic spaces}

An adic space is an object in $\mathcal{V}$ which has an open cover by subsets each isomorphic to $\Spa(A)$ for some Huber pair $A$. The isomorphism takes place in $V^{\pre}$, but we do not need these proofs which we just skipped : an isomorphism of objects in $\mathcal{V}^{\pre}$ is just an isomorphism of topological spaces and an isomorphism of presheaves which induces an isomorphism of stalks such that the valuation on one is equivalent to the pullback of the valuation on the other.

I guess formally one could say this as follows. The category $\mathcal{V}^{\pre}$  is a full subcategory of a bigger category where we drop the things that we cannot prove -- we drop the demand that the stalks are local and we drop the demand that the valuations on the stalks have support equal to the maximal ideal. Let $\mathcal{C}$ denote this bigger category. We still demand that the morphisms are compatible with the valuations on the stalks. We can prove that $\Spa(A)$ is an object of $\mathcal{C}$. But because isomorphisms in $\mathcal{V}^{\pre}$ have the same definition as isomorphisms in $\mathcal{C}$ we can still define an adic space to be an object of $\mathcal{V}$ which has an open cover such that the induced objects of $\mathcal{C}$ are isomorphic in $\mathcal{C}$ to things of the form $\Spa(A)$.

\end{document}


\documentclass{amsart}
\usepackage[english]{babel}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\newtheorem{Lemma 1}{Lemma}[section]
\newtheorem{Theorem}[Lemma 1]{Theorem}
\newtheorem{Lemma 3}[Lemma 1]{Lemma}
\newtheorem{Lucas The}[Lemma 1]{Theorem}
\newtheorem{num}[Lemma 1]{Lemma}
\newtheorem{lem}[Lemma 1]{Lemma}
\newtheorem{lemme}[Lemma 1]{Lemma}
\newtheorem{lem 1}[Lemma 1]{Lemma}
\newtheorem{Main}[Lemma 1]{Theorem}
\newtheorem{Corollary}[Lemma 1]{Corollary}
\newtheorem{Corollary 1}[Lemma 1]{Corollary}
\newtheorem{Corollary 2}[Lemma 1]{Corollary}
\begin{document}
\title{On Integer sequences in Product sets}
\address{Department of Mathematics, Indian Institute of Technology Roorkee,India 247667}
\author{Sai Teja Somu}
\date{April 2 , 2017}
\maketitle
	\begin{abstract}Let $B$ be a finite set of natural numbers or complex numbers. Product set corresponding to $B$ is defined by $B.B:=\{ab:a,b\in B\}$. In this paper we give an upper bound for longest length of consecutive terms of a polynomial sequence present in a product set accurate up to a positive constant. We give a sharp bound on the maximum number of Fibonacci numbers present in a product set when $B$ is a set of natural numbers and a bound which is accurate up to a positive constant when $B$ is a set of complex numbers.
	\end{abstract}
	\section{Introduction}
	In \cite{A} and \cite{B} Zhelezov has proved that if $B$ is a set of natural numbers then the product set corresponding to $B$ cannot contain long arithmetic progressions. In \cite{A} it was shown that the longest length of arithmetic progression is at most $O(|B|\log |B|)$. We try to generalize this result for polynomial sequences. Let $P(x)\in \mathbb{Z}[x]$ be a non constant polynomial with positive leading coefficient. Let $R$ be the longest length of consecutive terms of the polynomial sequence contained in the product set $B.B$, that is, \[R=max\{n : \text{there exists an $x\in \mathbb{N}$ such that }  \{P(x+1),\cdots,P(x+n)\}\subset B.B\}.\]We prove that $R$ cannot be large for a given non constant polynomial $P(x)$. In section 3 we consider the question of determining maximum number of Fibonacci and Lucas sequence terms in a product set.
	Let $A\times B$ denote the cartesian product of sets $A$ and $B$.As in \cite{A} we define an auxiliary bipartite graph $G(A, B.B)$ and auxiliary graph $G'(A,B.B)$ which are  constructed for any sets $A$ and $B$ whenever $A\subset B.B$.  The vertex set of $G(A,B.B)$ is a union of two isomorphic copies of $B$ namely $B_1=B\times\{1\}$ and $B_2=B\times\{2\}$ and vertex set of $G'(A, B.B)$ is one isomorphic copy of $B$ namely $B_1=B\times \{1\}$ . For each  $a\in A$we pick a unique representation $a = b_1b_2$ where $b_1,b_2\in B$ and place an edge joining $(b_1,1)$, $(b_2,2)$ in $G(A,B.B)$ and place an edge joining  $(b_1,1)$, $(b_2,1)$ in $G'(A,B.B)$.
	Note that the number of vertices in $G(A,B.B)$ is $2|B|$ where as number of vertices in $G'(A,B.B)$ is $|B|$. Number of edges in both $G(A,B.B)$ and $G'(A,B.B)$ is $|A|$. Observe that $G'(A,B.B)$ can have self loops and $G(A,B.B)$ cannot have self loops and that $G(A,B.B)$ is necessarily a bipartite graph where as $G'(A,B.B)$ may not be a bipartite graph.
	\section{Polynomial sequences}
	We deal the problem, given a non constant polynomial $P(x)$ with positive leading coefficient and integer coefficients what can we say about the longest length of consecutive terms in the product set $B.B$.
	Since there can be at most finitely many natural numbers $r$ such that $P(r)\leq0$ or $P'(r)\leq 0$ there exists an $l$ such that $P(r+l)>0$ and $P'(r+l)>0$ for all $r\geq 1$. Hence we can assume without loss of generality that every irreducible factor $g(x)$ of $P(x)$ we have $g(x)>0 \text{ and } g'(x)>0~~ \forall x\geq 1$, as this assumption only effects $R$ by a constant. From now on we will be assuming that for every irreducible divisor $g(x)$ of $P(x)$, $g(x)>0$ and $g'(x)>0$ for all natural numbers $x$.    We prove three lemmas in order to obtain an upper bound on $R$.
	From now we let $f(x)\in \mathbb{Z}[x]$ denote an irreducible polynomial divisor of $P(x)$.  If $f(x)$ is a polynomial of degree $\geq 2$. Let $D$ be the discriminant of $f(x)$. Let $d$ be the greatest common divisor of the set $\{f(n): n\in \mathbb{N}\}$. Let $f_1(x)=\frac{f(x)}{d}$.  Denote $|D|d^2$ by $M$. If $p$ is a prime divisor of $M$ such that $p^e||M$, that is $p^e|M$ and $p^{e+1}\nmid M$,  then $p^e\nmid d$ and hence there exists an $a_p$, such that $f_1(x)$ is not divisible by $p$ for all $x\equiv a_p (\mod p^e)$.   From Chinese remainder theorem there exists an integer $a$ such that $a\equiv a_p(\mod p^e)$ for all primes $p$ dividing $M$ and hence there exists an $a$ such that $f_1(x)$ is relatively prime to $M$ for all $x\equiv a (\mod M)$.
	\begin{num}\label{Lemma 4} For sufficiently large $R$the number of numbers in the set $\{f_1(r+i) : 1\leq i \leq R,r+i\equiv a \mod M \}$ with at least one prime factor greater than $R$ is $\geq \frac{R}{3M}$ for every non negative integer $r$. \end{num}\begin{proof}Let \[Q=\prod_{\substack{i=1\\r+i\equiv a\mod M}}^{R}f_1(r+i).\]Let $S$ be the largest divisor of $Q$ such that all the prime factors of $S$ are $\leq R$.Let $e_p$ be the index of $p$ in $S$, that is $p^{e_p}|S$ and $p^{e_p+1}\nmid S$. Let $\rho(p)$ denote the number of solutions modulo $p$ of the congruence $f(x)\equiv 0 (\mod p)$.We have,\begin{align}\log S&=\sum_{\substack{p\nmid M\\p\leq R}}e_p\log p \\&=\sum_{\substack{p\nmid M\\p\leq R}}\sum_{n=1}^{\lfloor\frac{\log f_1(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\r+i\equiv a\mod M\\f_1(r+i)\equiv 0 \mod p^n}}\log p.\label{key}\end{align}For a prime $p\nmid M$, as $p$ does not divide the discriminant of $f(x)$, each root $x$ of $f_1(x)\equiv 0 (\mod p)$ is a simple root modulo $p$ and each root $x$ modulo $p$ can be uniquely lifted to a solution $x'$ modulo $p^n$ of $f_1(x)\equiv 0 (\mod p^n)$. Hence number of solutions modulo $p^n$ of $f_1(x)\equiv 0(\mod p^n)$ is $\rho(p)$. From Chinese remainder theorem, each solution $x$ modulo $p^n$ such that $f_1(r+x)\equiv 0 (\mod p^n)$ with an additional congruence $r+x\equiv a (\mod M)$ corresponds to a unique solution modulo $Mp^n$. Hence number of solutions $x$ modulo $Mp^n$ such that $f_1(r+x)\equiv 0 (\mod p^n)$ and $r+x\equiv a (\mod M)$ is $\rho(p)$. From Lagrange's theorem, we have $\rho(p)\leq deg(f(x))$. Hence $\rho(p)=O(1).$
		Let $a_1,\cdots, a_{\rho(p)}$ be distinct solutions modulo $Mp^n$ of the congruences $f_1(r+x)\equiv 0 (\mod p^n)$ and $r+x\equiv a (\mod M)$. As for any $a_j$, \[\sum_{\substack{1\leq i \leq R\\i\equiv a_j(\mod Mp^n)}}1=\frac{R}{Mp^n}+O(1)\] we have,
		\begin{align*}\sum_{\substack{1\leq i \leq R\\r+i \equiv a(\mod M)\\f_1(r+i)\equiv 0(\mod p^n)}}\log p&=(\log p)\left(\sum_{j=1}^{\rho(p)}\sum_{\substack{1\leq i \leq R\\i \equiv a_j(\mod Mp^n) }}1\right)\\&=(\log p)\left( \sum_{j=1}^{\rho(p)}\frac{R}{Mp^n}+O(1)\right)\\&=\frac{R\rho(p)\log p }{Mp^n}+O(\log p).\end{align*}Combining the above result with (\ref{key}) we get \begin{align}&\log S=\sum_{\substack{p\nmid M\\p\leq R}}\sum_{n=1}^{\lfloor \frac{\log f_1(r+R)}{\log p} \rfloor}\left(\frac{R\rho(p)\log p }{Mp^n}+O(\log p)\right)\\&=\frac{R}{M}\sum_{\substack{p\nmid M\\p \leq R}}\frac{\rho(p)\log p}{p}+\frac{R}{M}\left(\sum_{\substack{p\nmid M\\p\leq R}}\sum_{n=2}^{\lfloor \frac{\log f_1(r+R)}{\log p} \rfloor} \frac{\log p}{p^n}\right)+\sum_{\substack{p\nmid M\\p\leq R}}\sum_{n=1}^{\lfloor \frac{\log f_1(r+R)}{\log p} \rfloor}O(\log p)\label{key_1}\end{align}

		From prime ideal theorem( See Theorem 3.2.1 of \cite{E}), we have\[ \sum_{p\leq x}\rho(p)=\text{li } x+O(xe^{-c\sqrt{\log x}})\] for some constant $c>0$. Using partial summation, we have \[ \sum_{p\leq x}\frac{\rho(p)\log p}{p}=\log x+O(1).\]Hence the first term of (\ref{key_1}) is\[\frac{R}{M}\sum_{\substack{p\nmid M\\p\leq R}}\frac{\rho(p)\log p }{p}=\frac{R\log R}{M}+O(R).\]As $\left(\sum_{\substack{p\nmid M\\p\leq R}}\sum_{n=2}^{\lfloor \frac{\log f_1(r+R)}{\log p} \rfloor} \frac{\log p}{p^n}\right)=O(1)$ the second term of (\ref{key_1}) is $O(R)$. As $\log f_1(r+R)=O(\log (r+R))$ and number of primes not dividing $M$ and less than $R$ is $O(\frac{R}{\log R})$ we have the following estimate of third term of ($\ref{key_1}$)\begin{align*}\sum_{\substack{p\nmid M\\p\leq R}}\sum_{n=1}^{\lfloor \frac{\log f_1(r+R)}{\log p} \rfloor}O(\log p)=O\left(\frac{R\log (r+R)}{\log R}\right).\end{align*}

		Combining the results of each term of (\ref{key_1}), we have\begin{equation}\label{equation}\log S=\frac{R\log R}{M}+O\left(\frac{\log (r+R)R}{\log R}\right). \end{equation}

		Let $L$ be a subset of $\{f_1(r+i) : 1\leq i\leq R,r+i\equiv a \mod M\}$ containing all the numbers which do not contain any prime factor greater than $R$ and let $l$ denote the cardinality of $L$. We have the inequality,\begin{align}\log \prod_{\substack{i=1\\f_1(r+i)\in L}}^{R}f_1(r+i)&\geq \log \prod_{i=1}^{l}f_1(r+i)\\&=n\sum_{i=1}^{l}\log (r+i)+O(l)\\&=nl\log (r+l)+O(l)\\&\geq 2l\log (r+l)+O(l)\label{key_3},\end{align}where $n\geq 2$ is the degree of the polynomial $f(x)$.Hence as $\prod_{\substack{i=1\\f_1(r+i)\in L}}^{R}f_1(r+i)|S$, we have the inequality,
		\[\log \prod_{\substack{i=1\\f_1(r+i)\in L}}^{R}f_1(r+i)\leq \log S.\] Hence from (\ref{equation}) and (\ref{key_3}) we have\begin{equation*}2l\log (r+l)+O(l)\leq \frac{R\log R}{M}+O\left(\frac{\log (r+R)R}{\log R}\right).\end{equation*}Hence for sufficiently large $R$, $l$ should be less than $ \frac{2R}{3M}-2$.  The number of numbers in the set $\{f_1(r+i) : 1\leq i \leq R,r+i\equiv a \mod M\}$ is $\geq \frac{R}{M}-1$. Hence number of numbers belonging to the set $\{f_1(r+i) : 1\leq i \leq R,r+i\equiv a \mod M\}$ with at least one prime factor greater than $R$ is $\geq \frac{R}{3M}$.\end{proof} The following corollary immediately follows from Lemma \ref{Lemma 4}. \begin{Corollary}\label{Corollary}If $P(x)\in \mathbb{Z}[x]$ has an irreducible divisor of degree $\geq 2.$ Then there exists a constant $c>0$ which may depend on $P(x)$ and independent of $R$ such that for sufficiently large $R$ and any non negative integer $r$, there are at least $cR$ numbers in the set $\{P(r+i) : 1\leq i \leq R\}$  having at least one prime factor greater than $R$. \end{Corollary}

	\begin{lem}\label{Lemma 5} If $f(x)$ is a linear polynomial. If $r\geq R^\gamma$ for a $\gamma >1$ then there exists a constant $c>0$ depending upon $\gamma$ such that for sufficiently large $R$, number of numbers in the set $\{f(r+i) : 1\leq i \leq R\}$ with a prime factor greater than $R$ is greater than $cR$.\end{lem}\begin{proof}The proof is similar to that of Lemma \ref{Lemma 4}.Let $Q=\prod_{i=1}^{R}f(r+i)$and $S$ be the largest divisor of $Q$ such that all the prime factors  $\leq R$, let $f(x)=sx+t$. Let $e_p$ be the index of prime $p$ dividing $S$.\begin{align}\log S&=\sum_{p\leq R}e_p\log p\\&=\sum_{p\leq R}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\f(r+i)\equiv 0 \mod p^n}}\log p\\&=\sum_{\substack{p\leq R\\p\nmid s}}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\f(r+i)\equiv 0 \mod p^n}}\log p+\sum_{\substack{p\leq R\\p| s}}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\f(r+i)\equiv 0 \mod p^n}}\log p. \label{key_4}\end{align}If $p\nmid s$ then $f(r+x)\equiv 0 (\mod p^n)$ has a unique solution modulo $p^n$. Let $a_1$ be the unique solution modulo $p^n$. Then \begin{align*}\sum_{\substack{1\leq i \leq R \\ f(r+i)\equiv 0 (\mod p^n)}}\log p = \sum_{\substack{1\leq i \leq R\\i\equiv a_1 (\mod p^n)}}\log p\\=\frac{R\log p}{p^n}+O(\log p).\end{align*}Observe that $\log f(r+i)= O(\log (r+i))$. Hence the first term of (\ref{key_4}) is \begin{align}\sum_{\substack{p\leq R\\p\nmid s}}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\f(r+i)\equiv 0 \mod p^n}}\log p=\sum_{\substack{p\leq R\\p\nmid s}}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\left(\frac{R\log p}{p^n}+O(\log p)\right)\\=R\sum_{\substack{p\leq R\\p\nmid s}}\frac{\log p}{p}+R\sum_{\substack{p\leq R\\p\nmid s}}\sum_{n=2}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\left(\frac{\log p}{p^n}\right)+\sum_{\substack{p\leq R \\ p\nmid s}}O(\log (r+R))\label{key_5}\end{align}We have \[\sum_{\substack{p\leq R\\p\nmid s}}\frac{\log p}{p}=\log R+O(1),\] \[\sum_{\substack{p\leq R\\p\nmid s}}\sum_{n=2}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\left(\frac{\log p}{p^n}\right)=O(1)\] and  \[\sum_{\substack{p\leq R \\ p\nmid s}}O(\log (r+R))=O\left(\frac{R\log(r+R)}{\log R}\right).\] Substituting the above results in (\ref{key_5}) we obtain the value of first term of (\ref{key_4}) \begin{equation}\label{key_6}\sum_{\substack{p\leq R\\p\nmid s}}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\f(r+i)\equiv 0 \mod p^n}}\log p=R\log R+O\left(\frac{R\log(r+R)}{\log R}\right).\end{equation}If $p|s$ such that $p^k|s$ and $p^{k+1}\nmid s$. Note that $p^k\leq s$.  The number of solutions of $f(r+x)\equiv 0 (\mod p^n)$ is less than or equal to $p^k$. Let $a_1,\cdots,a_{s_1}$ be the distinct solutions modulo $p^n$. We have $|s_1|\leq p^k\leq s$ for all $n$. Note that \begin{align*}\sum_{\substack{1\leq i \leq R\\f(r+i)\equiv 0 (\mod p^n)}}\log p&= \sum_{j=1}^{s_1}\sum_{\substack{1\leq i \leq R\\ i\equiv a_j (\mod p^n)}}\log p\\&=\sum_{j=1}^{s_1}(\log p)\left(\frac{R}{p^n}+O(1)\right)\\&=s_1\left( \frac{R\log p}{p^n} +O(\log p)\right)\\&\leq s\left( \frac{R\log p}{p^n} +O(\log p)\right).\end{align*}Using the above result we obtain an estimate on second term of (\ref{key_4})\begin{align}\sum_{\substack{p\leq R\\p| s}}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\f(r+i)\equiv 0 \mod p^n}}\log p&\leq \sum_{\substack{p\leq R\\p|s}}\sum_{n=1}^{\lfloor \frac{\log f(r+R)}{\log p}\rfloor}s\left(\frac{R \log p}{p^n}+O(\log p)\right).\label{second}\end{align}As there are only $O(1)$ number of prime factors of $s$ and $\log f(r+R)=O(\log (r+R)) $ we have  \[ \sum_{\substack{p\leq R\\p|s}}\sum_{n=1}^{\lfloor \frac{\log f(r+R)}{\log p}\rfloor}s\left(\frac{R \log p}{p^n}\right)=O(R)\] and \[ \sum_{\substack{p\leq R\\p|s}}\sum_{n=1}^{\lfloor \frac{\log f(r+R)}{\log p}\rfloor} O(s\log p)=O(\log (r+R)).\]Combining the above two results in (\ref{second}) we have an estimate for the second term of (\ref{key_4})\begin{equation}\label{second_term}\sum_{\substack{p\leq R\\p| s}}\sum_{n=1}^{\lfloor\frac{\log f(r+R)}{\log p}\rfloor}\sum_{\substack{1\leq i\leq R\\f(r+i)\equiv 0 \mod p^n}}\log p=O(R+\log (r+R)).\end{equation}From (\ref{key_4}), (\ref{key_6}) and (\ref{second_term}) we have \begin{equation}\label{main}\log S=R\log R+O\left(\frac{R\log (r+R)}{\log R}\right).\end{equation} Let $L$ be a subset of \{$1\leq i\leq R$\} containing all $i$ such that $f(r+i)$ has all prime factors $\leq R$. Let the cardinality of $L$ be $l$.\begin{align*}\log \prod_{\substack{i=1\\i\in L}}^{R}f(r+i)&\geq \log \prod_{i=1}^{l}f(r+i)\\&=l\log (r+R) +O(R). \end{align*}As $\prod_{\substack{i=1\\i\in L}}^{R}f(r+i)|S$ we have $\log \prod_{\substack{i=1\\i\in L}}^{R}f(r+i)\leq \log S$. From (\ref{main}) and the above inequality we have \begin{equation*} l \log (r+R)+O(R)\leq R\log R +O\left(\frac{R\log(r+R)}{\log R}\right).\end{equation*}For sufficiently large $R$, $l$ should be $\leq \frac{(1+\gamma)}{2\gamma}R$. Hence for sufficiently large $R$ number of numbers of the set $\{f(r+i) : 1\leq i \leq R  \}$ with at least one prime factor greater than $R$ is $\geq \frac{(\gamma-1)R}{2\gamma }$.\end{proof}We have the following Corollary for Lemma \ref{Lemma 5}.\begin{Corollary 1}\label{Corollary 2}If degree of every irreducible divisor of $P(x)$ is 1 and $\gamma>1$ then there exists a positive constant $c$ such that the number of elements of the set  $\{P(r+i): 1\leq i \leq R\}$ having at least one prime factor greater than $R$ is greater than $cR$ for sufficiently large $R,r$ satisfying the inequality $r\geq R^\gamma$.\end{Corollary 1}

	\begin{lemme}\label{Lemma 6}Let $f(x)$ be a linear polynomial.If $r\leq R^\gamma$ for some $\gamma>1$ then there are at least $c\frac{R}{\log R}$ numbers of the set $\{f(r+i): 1\leq i \leq R \}$ with at least one prime factor greater than $\frac{R}{2}$ for a constant $c>0$ and sufficiently large $R$. \end{lemme}\begin{proof}Let $f(n)=sn+t$ then there are at least $c_1(\frac{R}{\log R})$ primes between $(\frac{R}{2},R]$ which are coprime to $s$, for a constant $c_1>0$. Each prime in the interval $(\frac{R}{2},R]$ has one or two $i\in [1,R]$ such that $p|f(r+i)$. For each $f(r+i)$ there are at most $O(1)$ prime divisors belonging to $(\frac{R}{2},R]$. Hence there are at least $c\frac{R}{\log R}$ numbers with at least one prime factor greater than $\frac{R}{2}$ for sufficiently large $R$ and for some constant $c>0$.\end{proof}
	\begin{Corollary 2}\label{Corollary 3}If degree of every irreducible divisor of $P(x)$ is 1 and $r\leq R^\gamma$ then number of elements of the set  $\{P(r+i): 1\leq i \leq R\}$ with at least one prime factor belonging to the range $(\frac{R}{2},R]$ is greater than $c\frac{R}{\log R}$ for a constant $c>0$ and for sufficiently large $R$.\end{Corollary 2}
	In a graph $G(V,E)$ for $v\in V$ we define $V(v)$ to be the set of all vertices adjacent to $v$. Now we require a graph theoretic result in order to obtain an upper bound on $R$.
	\begin{lem 1}\label{Lemma 7}If there is a bipartite graph $(A,B,E)$ such that for all $a\in A$ and $b\in B$, degree of $a$ is $\leq n$ and degree of $b$ is $\geq 1$ then there exists a sequence of vertices $b_1,\cdots,b_k$ with $b_i\in B$ satisfying $V(b_1)\neq \phi$ and $V(b_i)/(\cup_{j=1}^{j=i-1}V(b_j))\neq \phi$ for $2\leq i\leq k$ and $k\geq \frac{|B|}{n}$.\end{lem 1}\begin{proof}The proof is by induction on $n$. For $n=1$ the lemma is true since degree of $a\leq 1~~ \forall ~ a\in A\implies V(b_1)\cap V(b_2)=\phi ~~\forall~ b_1\neq b_2\in B$ and the sequence $b_1,\cdots, b_{|B|}$ will clearly satisfy $V(b_1)\neq \phi$ and $V(b_i)/(\cup_{j=1}^{i-1}V(b_j))\neq \phi$ for  $2\leq i\leq k$.If the lemma is true for $n=r$ we have to prove for $n=r+1$. Order the vertices of $B$ as $b_1,\cdots b_{|B|}$. Let $S=\{a\in A : \text{degree of $a$}\geq 1\}$.Let $S_1=V(b_1)$ and for $2\leq i \leq |B|$, let  $S_i=V(b_i)/(\cup_{j=1}^{i-1}V(b_j))$.Observe that $S=\cup_{i=1}^{|B|}S_i$.Let $K$ be a set defined by $K=\{b_i : S_i\neq \phi\}$.If $|K|\geq \frac{|B|}{r+1}$ then we can choose the vertices in the set $K$ arranged in a sequence which satisfies the hypothesis.If $|K|<\frac{|B|}{r+1}$ then consider the induced subgraph $A\cup (B/K)$ then degree of $a$ is less than or equal to $r$ for all $a\in A.$ From the induction assumption there exists a sequence with length $\geq \frac{|B/K|}{r}>|B|(1-\frac{1}{r+1})\frac{1}{r}=\frac{|B|}{r+1}$ in $B/K$ satisfying the hypothesis which completes the proof by induction.   \end{proof}Now we prove the main theorem.\begin{Main}If $P(x)\in \mathbb{Z}[x]$ is a non constant polynomial with a positive leading coefficient and $B$ is a set of complex numbers. If $\{P(r+1),\cdots,P(r+R)\}$ is contained in the product set $B.B$ for a nonnegative integer $r$ and a natural number $R$. Then  \newline(1)If $P(x)$ has an irreducible factor of degree $\geq 2$ then $R=O(|B|)$. In this case the implicit constant only depends on $P(x)$.\newline(2)If $P(x)$ has no irreducible factor of degree $\geq 2$ and there exists a $\gamma>1$ such that $r>R^\gamma$ then $R=O(|B|)$. In this case the implicit constant depends on $P(x)$ and $\gamma$. \newline(3)If $P(x)$ has no irreducible factor of degree $\geq 2$ and there exists a $\gamma>1$ such that $r\leq R^\gamma$ then $R=O(|B|\log |B|)$. In this case the implicit constant depends on $\gamma$ and $P(x)$.\end{Main}\begin{proof}If $P(x)$ has an irreducible factor $f(x)$ of degree  $\geq2$ or $P(x)$ has no irreducible divisor of degree $\geq 2$ and $r> R^\gamma$ for some $\gamma>1$ let \begin{equation*}A=\{p : \text{$p$ is a prime,~$p|P(r+i)$ for some $1\leq i\leq R$,~$p>R$}\}\end{equation*}and let\begin{equation*}C=\{P(r+i) : \text{$1\leq i \leq R$,$\exists$ prime $p>R$ \text{ such that }  $p|P(r+i)$}\}.\end{equation*}If $P(x)$ has no irreducible divisor of degree $\geq 2$ and $r\leq R^\gamma$ for some $\gamma>1$ then let \begin{equation*}A=\{p : \text{$p$ is a prime, $\frac{R}{2}< p\leq R$ and $p|P(r+i)$ for some $1\leq i \leq R$}\}\end{equation*}and let \begin{equation*}C=\{P(r+i) : \text{$1\leq i \leq R$,$\exists$ prime $p\in (\frac{R}{2},R]$ \text{ such that } $p|P(r+i)$}\}.\end{equation*}In cases (1) and (2) from Corollaries \ref{Corollary} and \ref{Corollary 2} the size of $C$ is greater than $cR$ for some constant $c>0$ ($c$ depends only on $P(x)$ in case (1) and depends on $P(x)$ and $\gamma$ in case (2)) and for sufficiently large $R$. In case (3) from Corollary \ref{Corollary 3} the size of $C$ is greater than $c\frac{R}{\log R}$ for sufficiently large $R$ and for some constant $c>0$ which depends on $\gamma$ and $P(x)$.If we consider a bipartite graph $G$ between $A\cup C$ constructed such that there exits an edge $p\in A$ and $P(r+i)\in C$ if and only if $p|P(r+i)$. Let degree of $P(x)$ be $d$. In this graph, from Lagrange's theorem the degree of $a\in A$ is less than or equal to the degree of polynomial $P(x)$ in case (1) and (2) and less than twice the degree of polynomial $P(x)$ in case (3) . Hence from Lemma \ref{Lemma 7} there exists a sequence $c_1,c_2,\cdots ,c_k\in C$ with $k\geq \frac{|C|}{2d}$ such that $V(c_1)\neq \phi$ and $V(c_i)/\cup_{j=1}^{k-1}V(c_j)\neq \phi$.  Therefore every $c_i$ has a prime divisor which does not divide any of $c_j$ for $1\leq j \leq i-1$. Let  $C'=\{c_1,\cdots,c_k\}$. Note that in cases (1) and (2) we have $|C'|\geq \frac{c}{2d}R$  and in case (3) we have $|C'|\geq \frac{cR}{2d\log R}$ for sufficiently large $R$.
		Consider the bipartite auxiliary graph $G(C',B.B)$. We claim that there cannot be any cycle in this graph. Note that the vertex set of $G(C',B.B)$ is $B\times\{1\}\cup B\times\{2\}$ Suppose there was a cycle, since it is a bipartite graph, cycle length has to be an even number and there will be a cycle of the form  $(b_1,1)(b_2,2)\cdots (b_{2k},2)(b_1,1)$ where $b_i's$ belong to $B$ then \begin{align*}  b_1b_2&=c_{n_1}\\  b_2b_3&=c_{n_2}\\        &.       \\        &.\\        &.\\  b_{2k}b_1&=c_{n_{2k}}    \end{align*}for some $n_i$'s such that $1\leq n_i\leq k$ and $n_i\neq n_j$ for $i\neq j$. Then it is easy to observe the relation \begin{equation}\label{contradiction}\prod_{i=1}^{k}c_{n_{2i}}=\prod_{j=1}^{k}c_{n_{2j-1}}\end{equation}let $n_i$ be the largest element of the set $\{n_1, \cdots,n_{2k}\}$. There exists a prime $p$ such that $p|c_{n_i}$ and $p\nmid c_{n_j}$ for $j\neq i$ and hence $p$ divides exactly one side of (\ref{contradiction}) and hence (\ref{contradiction}) cannot be true. Thus there exists no cycle in $G(C',B.B)$. In any graph without self loops, if there exists no cycle then the numbers of edges is strictly less than number of vertices. Hence $|C'|\leq 2|B|-1$.  As in cases (1) and (2) we have $|C'|\geq \frac{c}{2d}R$  and in case (3) we have $|C'|\geq \frac{cR}{2d\log R}$ for sufficiently large $R$.Therefore $R=O(|B|)$ in cases (1),(2) and $R=O(|B|\log |B|)$ in case (3) which completes the proof of the theorem. \end{proof}
	\section{Number of Fibonacci Numbers and Lucas Numbers in a Product set}
	Let $B$ be a finite set of naural numbers. Let $A$ be the set of Fibonacci numbers contained in the product set $B.B$. From \cite{C} there are only two perfect square Fibonacci numbers, viz., $1$ and $144$. Hence there can be at most two self loops in the  graph $G'(A,B.B)$. We give an upper bound on the cardinality of $A$ by using the following lemma.
	\begin{Lemma 1}\label{Lemma}Let $F_n$ and $F_m$ be $n$th and $m$th Fibonacci numbers and $m<n$ and $n>2$ then $gcd(F_n,F_m)<\sqrt{F_n}$.\end{Lemma 1}\begin{proof}Let $d=gcd(m,n)$. From the strong divisibilty property of Fibonacci numbers $gcd(F_n,F_m)=F_{d}$. We know that $F_n=\frac{\alpha^n-\beta^n}{\alpha-\beta},$ where $\alpha=\frac{1+\sqrt{5}}{2}$ and $\beta=\frac{1-\sqrt{5}}{2}$. Since $m<n$, clearly $d\leq \frac{n}{2}$.  If $d=1$ then the hypothesis is clearly true and if $d>1$, we have\begin{equation*}(F_d)^2=\frac{(\alpha^d-\beta^d)^2}{(\alpha-\beta)^2}< \frac{(\alpha^{2d}-\beta^{2d})}{(\alpha-\beta)}\leq F_n.\end{equation*}Thus, $gcd(F_m,F_n)<\sqrt{F_n}$.\end{proof}
	\begin{Theorem}There cannot be more than $|B|$ Fibonacci numbers in the product set $B.B$ when $B$ is a set of natural numbers.\end{Theorem}\begin{proof}We claim that in the graph $G'(A,B.B)$ there cannot any cycle other than self loops. Suppose there is a $k$-cycle of the form $(b_1,1)(b_2,1)\cdots (b_k,1)(b_1,1)$ where $b_i\in B$ for $1\leq i \leq k$. We now have the information that $b_ib_{i+1}$ for $1\leq i \leq k-1$ and $b_kb_1$ are distinct Fibonacci numbers in the set $B.B$. Without loss of generality let us assume $b_1b_2=F$ is the largest Fibonacci number among $b_ib_{i+1}$ for $1\leq i \leq k-1$ and $b_kb_1$.From Lemma \ref{Lemma}, we have \begin{align*}& b_1\leq gcd(b_1b_2,b_1b_k)<\sqrt{F},\\& b_2\leq gcd(b_1b_2,b_2b_3)<\sqrt{F}.\end{align*}Hence $F=b_1b_2<F$ which is a contradiction.Hence there cannot be any cycle. From \cite{C} there cannot be more than 2 self loops.Hence the number of edges which equal number of Fibonacci numbers in the set $B.B$ cannot exceed $|B|+1$.
		Now we prove that there cannot be $|B|+1$ Fibonacci numbers in $B.B$. Suppose there are $|B|+1$ Fibonacci numbers, as the graph cannot have any cycle there should be two self loops namely, $(1,1)$ and $(12,1)$, and $1,12\in B$ and the graph obtained by removing the two self loops should be connected tree of $|B|$ vertices. Since the graph is connected there should be a path between $(1,1)$ and $(12,1)$. Let the path be $(b_1,1)(b_2,1)\cdots (b_k,1)$ which implies that  $b_ib_{i+1}$ for $1\leq i\leq k-1$ are Fibonacci numbers and without loss of generality assume $b_1=1$ and $b_k=12$. Let $l$ be the index of highest value of $b_ib_{i+1}$, that is $b_lb_{l+1}$ is the largest Fibonacci number among $b_ib_{i+1}$ for $1\leq i\leq k-1$. Clearly $l\neq 1$ and if $2\leq l\leq k-2$ then from Lemma \ref{Lemma} we have  \begin{align*}& b_l\leq gcd(b_lb_{l+1},b_{l-1}b_l)<\sqrt{b_lb_{l+1}},\\& b_{l+1}\leq gcd(b_lb_{l+1},b_{l+1}b_{l+2})<\sqrt{b_lb_{l+1}}.\end{align*}Which implies $b_lb_{l+1}<b_lb_{l+1}$. Hence $l=k-1$. Again from Lemma \ref{Lemma}\begin{equation*}b_{k-1}\leq gcd(b_{k-1}b_k,b_{k-2}b_{k-1})<\sqrt{b_{k-1}b_k}\end{equation*}which implies $b_{k-1}<b_k=12$ but there are no Fibonacci numbers of the form $12b$ with $b<12$.Hence there cannot be $|B|+1$ Fibonacci numbers. Thus number of Fibonacci numbers in the set $B.B$ is $\leq |B|$. \end{proof}Now we consider the case where $B$ is a set of complex numbers and try to give an upper bound on the number of Lucas sequence terms in the product set. Let $A$ be the set of Lucas sequence terms with indices greater than $30$ in the  product set $B.B$.
	\begin{Lemma 3}\label{Lemma 3}There cannot be any cycle in $G(A,B.B)$.\end{Lemma 3}\begin{proof}Suppose there was a cycle,  then there will be a cycle of the form $(b_1,1)(b_2,2)\cdots (b_{2k},2)(b_1,1)$.Then \begin{align*}  b_1b_2&=L_{n_1}\\  b_2b_3&=L_{n_2}\\        &.       \\        &.\\        &.\\  b_{2k}b_1&=L_{n_{2k}},      \end{align*}where $L_{n_i}$ are Lucas sequence terms with indices greater than $30$, which implies\begin{equation}\label{Lucas}\prod_{i=1}^{k}L_{n_{2i}}=\prod_{j=1}^{k}L_{n_{2j-1}}\end{equation}Let $n_i$ be the largest index $\geq 31$. Then from \cite{D}, $L_{n_i}$ contains a primitive divisor $p$ and hence $p$ divides exactly one side of (\ref{Lucas}) and therefore (\ref{Lucas}) cannot be true. Thus there cannot be any cycle.\end{proof}
	\begin{Lucas The}Let $(L_n)_{n=1}^\infty$ be a Lucas sequence. Then the number of distinct elements of $(L_n)_{n=1}^\infty$ in $B.B$ is less than $2|B|+30$.\end{Lucas The}\begin{proof}Since the number of vertices in $G(A,B.B)$ is $2|B|$ and from Lemma \ref{Lemma 3} there cannot be a cycle in $G(A,B.B)$ and hence the number of edges in $G(A,B.B)$ is $\leq 2|B|-1$. Hence the number of distinct terms in Lucas sequence of index $\geq 31$ is $\leq 2|B|-1$. Hence number of distinct Lucas sequence terms in $B.B$ is $\leq 2|B|+29$.\end{proof}

	\bibliographystyle{amsplain}

	\begin{thebibliography}{10}

		\bibitem{D}Y. Bilu, G. Hanrot and P. Voutier, {\it  Existence of primitive divisors of Lucas and Lehmer numbers.} J. Reine Angew. Math. {\bf 539}(2001), 75-122.

	   \bibitem{C}Y. Bugeaud, M. Mignotte, and S. Siksek, {\it Classical and modular approaches  to exponential Diophantine equations. I. Fibonacci and Lucas perfect powers}, Ann. of Math. (2)  {\bf 163}:3 (2006), 969-1018.

	   \bibitem{E} Cojocaru, A. C., Murty, M. R. (2005). {\it An introduction to sieve methods and their applications} (Vol. 66). Cambridge University Press.

	   \bibitem {A} D. Zhelezov, {\it Improved bounds for arithmetic progressions in product sets},   International Journal of Number Theory 11, no. 08(2015), 2295-2303.

	   \bibitem {B}  D. Zhelezov, {\it Product sets cannot contain long arithmetic progressions}, Acta Arith. 163    (2014), 299-307.
   \end{thebibliography}
\end{document}

Number theory/somuteja's questions/On Integer Sequences in Product Sets.tex


\title{AMMM Project}
\author{Adrian Rodriguez Bazaga, Pau Rodriguez Esmerats }
\date{November 2017}

\begin{document}

\maketitle

\section{ Modelling }

\subsection{ Decision vars }

\begin{itemize}

\item $ w_{n,h} (\mathbb{B})  : \text{ whether the nurse n works at the hour h }  $
\item $ z_{n} (\mathbb{B})  : \text{ whether the nurse n works during the shift(24h) or not } $
	\begin{itemize}[label=$\star$]
 	\item $ z{n} = 1  \Rightarrow \text{ The nurse n works at least 1 hour, } \exists h, w_{n,h} = 1 $
 	\item $ z{n} = 0 \Rightarrow \forall h, w_{n,h} = 0 $
 	\end{itemize}
\item $  s_{n} (\mathbb{N}) : \text{hour in which the nurse n starts working,} \\ \text{  such that $ w_{n,s_{n}}=1 $ and  $ w_{n,s_{n}-i}=0 $,  $ \forall i: 1 \leq s_{n} - i < s_{n} $ } $
\item $  e_{n} (\mathbb{N}) : \text{hour in which the nurse n stops working,} \\ \text{such that $ w_{n,e_{n}}=1 $ and  $ w_{n,e_{n}+i}=0,\forall i : e_{n} < e_{n}+i \leq 24 $  } $
\end{itemize}

\subsection{  Known instance variables }

\begin{itemize}
\item  $ demand_h $
\item  $ nNurses  $
\item  $minHours $
\item  $maxHours $
\item  $maxConsec $
\item  $maxPresence $
\end{itemize}

\subsection{  Objective function }

Min: $ \sum\limits_{n=1}^{nNurses} z_{n}  $

\subsection{  Constraints }

\begin{itemize}
\item  set the zn values correctly:
$  \forall n: 1 \leq n \leq nNurses,  \\
	24 \cdot z_{n}  \geq \sum\limits_{1 \leq h \leq 24} w_{n,h} \\
   z_{n} \leq \sum\limits_{1 \leq h \leq 24} w_{n,h}
$

\item  At any hour h, at least demandh nurses should be working: \\
$ \forall h : 1 \leq h \leq 24, \\
 \sum\limits_{1 \leq n \leq nNurses} w_{n,h} \geq demand_{h}
$

\item  Each nurse that works, should work at least minHours: \\
$ \forall n: 1 \leq n \leq nNurses \\
	\sum\limits_{1 \leq h \leq 24} w_{n,h} \geq minHours \cdot z_{n}
$

\item  Each nurse that works, should work at most maxHours: \\
$ \forall n: 1 \leq n \leq nNurses \\
	\sum\limits_{1 \leq h \leq 24} w_{n,h} \leq maxHours \cdot z_{n}
$

\item  Each nurse works at most maxConsec consecutive hours: \\
$	\forall n:  1 \leq n \leq nNurses, \\
	\forall h_{1}:  1 \leq h_{1} \leq 24 - maxConsec, \\
	\sum\limits_{ h_{1} \leq h \leq h_{1} + maxConsec} w_{n,h} \leq maxConsec $

\item  Each nurse can stay in the hospital at most maxPresence hours: \\
$
%\forall n:  1 \leq n \leq nNurses, e_{n} \leq 24 \cdot z_{n} \\
 \forall n:  1 \leq n \leq nNurses, \forall h: 1 \leq h \leq 24, e_{n} \geq h \cdot w_{n,h} \\
 \forall n:  1 \leq n \leq nNurses, s_{n} \geq 0 \\
 \forall n:  1 \leq n \leq nNurses, \forall h: 1 \leq h \leq 24, s_{n} \leq (h - 24) \cdot w_{n,h} + 24 \cdot z_{n} \\
  \forall n:  1 \leq n \leq nNurses, e_{n} - s_{n} + 1 - (2 \cdot 24)\cdot(1 - z_{n}) \leq maxPresence \cdot z_{n} $ \\

\item  Each nurse can rest at most one consecutive hour (exam hint version):

$
\forall n:  1 \leq n \leq nNurses, \forall h: 2 \leq h \leq 23:  r_{n,h} = 1 - w_{n,h} \\
\forall n:  1 \leq n \leq nNurses, \forall h: 2 \leq h \leq 23:  wa_{n,h} = w_{n,h+1} \\
\forall n:  1 \leq n \leq nNurses, \forall h: 2 \leq h \leq 23:  wb_{n,h} = w_{n,h-1} \\
\forall n:  1 \leq n \leq nNurses, \forall h: 2 \leq h \leq 23, \forall M: M \geq 24  \\  M \cdot ( 1 - r_{n,h} ) + M \cdot wb_{n,h} - 24 \cdot wa_{n,h} +  24 \cdot r_{n,h}   \geq \sum\limits_{1 \leq h_{i} \leq h }  w_{n,h_{i}}  $ \\
which is equal to :  \\
$
2\cdot M \cdot ( 1 - r_{n,h} ) + M \cdot wb_{n,h} - M \cdot wa_{n,h} +  M \cdot r_{n,h}   \geq \sum\limits_{1 \leq h_{i} \leq h }  w_{n,h_{i}}  \\
$

\item  Each nurse can rest at most one consecutive hour:

$
\forall n:  1 \leq n \leq nNurses, \forall h: 2 \leq h \leq 22, \forall M: M \geq 24  \\ M - M \cdot w_{n,h-1} + M \cdot w_{n,h} + M \cdot w_{n,h+1}  \geq \sum\limits_{h+1 \leq h_{i} \leq 24 }  w_{n,h_{i}} \\	 $
can be rewritten as : \\
$
\forall n:  1 \leq n \leq nNurses, \forall h: 2 \leq h \leq 22, \forall M: M \geq 24  \\
M - M \cdot wb_{n,h} + M \cdot w_{n,h} + M \cdot wa_{n,h}  \geq \sum\limits_{h+1 \leq h_{i} \leq 24 }  w_{n,h_{i}} \\
M - M \cdot wb_{n,h} + M \cdot ( 1 - r_{n,h}) + M \cdot wa_{n,h}  \geq \sum\limits_{h+1 \leq h_{i} \leq 24 }  w_{n,h_{i}} \\
M \cdot ( 2 - r_{n,h}) - M \cdot wb_{n,h} +  M \cdot wa_{n,h}  \geq \sum\limits_{h+1 \leq h_{i} \leq 24 }  w_{n,h_{i}} \\
2 \cdot M \cdot ( 1 - r_{n,h}) - M \cdot wb_{n,h} +  M \cdot wa_{n,h} + M \cdot r_{n,h}  \geq \sum\limits_{h+1 \leq h_{i} \leq 24 }  w_{n,h_{i}} \\
2 \cdot M \cdot ( 1 - r_{n,h}) - M \cdot wb_{n,h} +  M \cdot wa_{n,h} + M \cdot r_{n,h}  \geq \sum\limits_{h \leq h_{i} \leq 24 }  w_{n,h_{i}} \\
$

\end{itemize}

\end{document}

\pagebreak


\subsection{RNN сети}
{\color{red}
https://arxiv.org/abs/1808.03314

A recurrent neural network (RNN) is a class of artificial neural networks where connections between nodes form a directed graph along a temporal sequence. This allows it to exhibit temporal dynamic behavior. Derived from feedforward neural networks, RNNs can use their internal state (memory) to process variable length sequences of inputs.[1][2][3] This makes them applicable to tasks such as unsegmented, connected handwriting recognition[4] or speech recognition.[5][6]

The term “recurrent neural network” is used indiscriminately to refer to two broad classes of networks with a similar general structure, where one is finite impulse and the other is infinite impulse. Both classes of networks exhibit temporal dynamic behavior.[7] A finite impulse recurrent network is a directed acyclic graph that can be unrolled and replaced with a strictly feedforward neural network, while an infinite impulse recurrent network is a directed cyclic graph that can not be unrolled.

Both finite impulse and infinite impulse recurrent networks can have additional stored states, and the storage can be under direct control by the neural network. The storage can also be replaced by another network or graph, if that incorporates time delays or has feedback loops. Such controlled states are referred to as gated state or gated memory, and are part of long short-term memory networks (LSTMs) and gated recurrent units. This is also called Feedback Neural Network (FNN).

}


\documentclass[12pt]{article}
\usepackage[english]{babel}
%\usepackage{subcaption}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{amsmath}
\graphicspath{{images/}}
\usepackage{geometry}
 \geometry{
 a4paper,
 total={170mm,257mm},
 left=15mm,
 top=15mm,
 }
\begin{document}
\section{Introduction}
In this project, we have estimated the 3D motion of camera, and provided as output a plot of the trajectory of the camera. The inputs given in this project are image frames of a driving sequence taken by a camera attached in front of the car. By estimating the motion of camera. we are indirectly estimating the motion of the car using the concepts of Visual Odometry.

\section{Pipeline followed}
The following pipeline was followed to implement this project.
\subsection{Data Preparation:} The input frames were in Bayer format from which we can recover the color images using the demosaic function with GBRG alignment. That is, convert the Bayer pattern encoded image to a color image using inbuilt Opencv function:

\begin{figure}[h]
    \centering
    \includegraphics[width=12cm]{data1}
\end{figure}

Then we extracted the camera parameters using $ReadCameraModel.py$ file provided.
\begin{figure}[h]
    \centering
    \includegraphics[width=14cm]{data2}
\end{figure}

Then we undistorted the images frames using $UndistortImage.py$ file provided.
\begin{figure}[h]
    \centering
    \includegraphics[width=12cm]{data3}
\end{figure}
Since, there were many image frames, for easy access and optimize the code, we converted the undistorted image sequence into a single video.

\subsection{Estimating Fundamental Matrix:}The fundamental matrix, denoted by F, is a 3x3 matrix of rank 2 that relates the corresponding set of points in two images from different views. Lets say a point $X$ in 3D is represented as $(x_i, y_i, 1)$ in camera $C1$ and $(x^{'}_i, y^{'}_i, 1)$ in camera $C2$. Fundamental matrix related these points in two different cameras using the following relation.
\newpage
\begin{figure}[h]
    \centering
    \includegraphics[width=13cm]{FM}
\end{figure}
The above equation can be modified to the matrix form $Ax = 0$
\begin{figure}[h]
    \centering
    \includegraphics[width=13cm]{FM2}
\end{figure}
Hence, the fundamental matrix can be found finding the SVD of matrix A, the decomposition $U*S*V^T$ would be obtained with U and V orthonormal matrices and a diagonal matrix S that contains the singular values. The last column of V is the true solution of the matrix equation $Ax = 0$ which lies in null space of matric A. The last column of V can be reshaped into fundamental matrx of size 3x3. This is done in the python file EstimateFundamentalMatrix.py. The fundamental matrix obtained is compared with the results obtained from cv2.findFundamentalMat Opencv function which uses 8-point algorithm. The results are shown below:
\begin{figure}[h]
    \centering
    \includegraphics[width=11cm]{funmat}
    \caption{Fundamental matrix comparison}
    \label{fig:Fundamental matrix comparison}
\end{figure}
\newline
The code snippet of the comparison is shown below:
\newpage
\begin{figure}[h]
    \centering
    \includegraphics[width=11cm]{funcode}
    \caption{Fundamental matrix comparison code}
    \label{fig:Fundamental matrix comparison code}
\end{figure}
\subsection{Match Outlier Rejection via RANSAC:}
The corresponding point in two images computed may be noisy. Thus, we may not get the correct estimate of the fundamental matrix. So, in order to get the correct estimate, we employ RANSAC algorithm to remove the outliers. After removing the outiers, the fundamental matrix F with maximum number of inliers is chosen. The RANSAC algorithm is implemented in GetInlierRansac2.py python file. The fundamental and essential matrix obtained by implementing RANSAC algorithm is compared with results from Opencv functions like  cv2.findEssentialMat and cv2.findFundamentalMat which uses RANSAC algorithm. The following are the results obtained:
\begin{figure}[h]
    \centering
    \includegraphics[width=11cm]{ransac}
    \caption{Fundamental and Essential matrix comparison RANSAC}
    \label{fig:Fundamental and Essential matrix comparison RANSAC}
\end{figure}
\newline
The reason why the function output and the Opencv output are different is because of RANSAC algorithm does not sample the points accurately.
The code snippet is given below:
\newpage
\begin{figure}[h]
    \centering
    \includegraphics[width=11cm]{ransac1}
    \caption{Fundamental and Essential matrix comparison RANSAC code}
    \label{fig:Fundamental and Essential matrix comparison RANSAC code}
\end{figure}
\subsection{Estimate Essential Matrix from Fundamental Matrix:}
We can find the relative camera poses between two images using the fundamental matrix F. In order to compute relative poses between two images we need to first compute essential matrix(E). In order to compute, essential matrix, we need to intrinsic matrix(K). The relation is given by:
\begin{figure}[h]
    \centering
    \includegraphics[width=3cm]{EM}
\end{figure}
\newline
By, due to noises present in matrix K, the third eigen value of matrix E is not zero. This can be corrected by reconstructing it with (1,1,0) singular values.
\begin{figure}[h]
    \centering
    \includegraphics[width=6cm]{EM2}
\end{figure}
This is implemented in EssentialMatrixFromFundamentalMatrix.py python file. The result of the essential matrix was verified by passing the camera matrix as identity matrix and was found that both fundamental and essential matrix was equal.
\newpage
\begin{figure}[h]
    \centering
    \includegraphics[width=10cm]{essmat}
    \caption{Essential matrix}
    \label{fig:Essential matrix}
\end{figure}
The code snippet of the comparison is shown below:
\begin{figure}[h]
    \centering
    \includegraphics[width=11cm]{esscode}
    \caption{Essential matrix comparison code}
    \label{fig:Essential matrix comparison code}
\end{figure}
\subsection{Estimate Camera Pose from Essential Matrix}
Camera pose refers to the position and angle at which the camera is places w.r.t to the world coordinates. Position of the camera refers to the center of the camera. The position and rotation of the camera can be determined by using essential matrix(E). First, we compute the svd of E.
\begin{figure}[h]
    \centering
    \includegraphics[width=2cm]{EM3}
\end{figure}
\newline
Then using the W matrix which is given by:
\newpage
\begin{figure}[h]
    \centering
    \includegraphics[width=4cm]{EM4}
\end{figure}
The camera center C and rotation of the camera R can be computes as follows:
\begin{enumerate}
\item $C_1 = U(:,3) , R_1 = U*W*V^{T}$
\item $C_2 = -U(:,3) , R_2 = U*W*V^{T}$
\item $C_3 = U(:,3) , R_3 = U*W*V^{T}$
\item $C_4 = -U(:,3) , R_4 = U*W*V^{T}$
\end{enumerate}
If the $det(R) = -1,$ the camera pose must be corrected i.e. $C=-C$ and $R=-R$. This is implemented in ExtractCameraPose.py python file. The camera pose obtained was compared with Opencv function cv2.decomposeEssentialMat function. The compared results are shown below:
\begin{figure}[h]
    \centering
    \includegraphics[width=9cm]{came}
    \caption{Pair of Rotation and Translation matrix obtained}
    \label{fig:Pair of Rotation and Translation matrix obtained}
\end{figure}
\newline
In Opencv, the function returns 2 rotation matrices(R,-R) and 1 translation matrix(T).Generally 4 possible poses exists for a given E. They are [R1, T], [R1, -T], [R2, T], [R2, -T]. These possible poses are exactly equal to the poses obtained from formula.
\begin{enumerate}
\item  $[R, T]  ->   [R1, C_1]$
\item  $[R, -T]  ->  [R2, C_2]$
\item  $[-R, -T]  -> [R3, C_3]$
\item  $[-R, -T]  -> [R4, C_4]$
\end{enumerate}
The results are shown below:
\begin{figure}[h]
    \centering
    \includegraphics[width=6cm]{came1}
    \caption{Rotation and Translation matrix obtained from Opencv}
    \label{fig:Rotation and Translation matrix obtained from Opencv}
\end{figure}
\newline
The code snippet of the comparison is shown below:
\begin{figure}[h]
    \centering
    \includegraphics[width=7.5cm]{camecode}
    \caption{Rotation and Translation matrix code}
    \label{fig:Rotation and Translation matrix code}
\end{figure}
\subsection{Linear Triangulation:}
Linear triangulation is a method to extract the 3D coordinates of a point in the image frame(X) from two different camera projections of the point$(x,x^{'})$ from 2 cameras.  From the camera matrix of two cameras($C_1, C_2$) which are $P,P^{'}$, we need to estimate the 3D coordinates of X using linear triangulation. \\
We know the relation between $(x,x^{'})$ and $P,P^{'}$ and X.
\begin{equation}
	x = PX
\end{equation}
\begin{equation}
	x^{'} = P^{'}X
\end{equation}
and we also know that
\begin{equation}
	cross(x, PX)= 0
\end{equation}
\begin{figure}[h]
    \centering
    \includegraphics[width=9cm]{formula}
\end{figure}
Third line is a linear combination of the first and second lines.  So, we can remove it. So, we get:
\begin{figure}[h]
    \centering
    \includegraphics[width=7cm]{formula1}
\end{figure}
By concatenating points from two images, we get:
\begin{figure}[h]
    \centering
    \includegraphics[width=5cm]{formula2}
\end{figure}
This is a system of homogenous linear equation of the form $Ax = 0$. The solution is obtained using svd. The goal is to minimize the error caused due to noise. So, we find the total least square approach to minimize the error. So, the solution is the eigen vector with least eigen value of $A^{T}*A$. This is implemented in LinearTriangulation.py python file.

\subsection{Triangulation Check for Cheirality Condition}
After getting the 3D coordinates from linear triangulation, we need to check whether the obtained point is in front or behind the camera. We always want our point to be in front of the camera. This is checked by using Cheirality condition. Cheirality condition checks the sign of the depth in the camera coordinate w.r.t camera center. The condition is given by:
\begin{equation}
r_3(X - C) > 0
\end{equation}
where $r_3$ is the third row of the rotation matrix.The best camera configuration, (C,R,X) is the one that produces the maximum number of points satisfying the cheirality condition. This is implemented in DisambiguateCameraPose.py python file.

\subsection{Plotting the motion of the camera:}
The final part of this pipeline is plotting the camera center based on translation and rotation between successive frames.
\begin{figure}[h]
    \centering
    \includegraphics[width=11cm]{output1}
    \caption{Camera Trajectory}
    \label{fig:Camera Trajectory}
\end{figure}

\section{Comparison:(Extra credit)}
The comparison is made by plotting the trajectory obtained from our method and using opencv functions like cv2.findEssentialMat and cv2.recoverPose. The results of the comparison are shown below:
\begin{figure}[h]
    \centering
    \includegraphics[width=11cm]{output2}
    \caption{Camera Trajectory comparison}
    \label{fig:Camera Trajectory comparison}
\end{figure}

\section{Output videos:}
To access the output video please click on this \href{https://drive.google.com/drive/folders/1bHtRRyyHCVfVULQ9rLM1Tsxr-f1liSLU?usp=sharing}{\underline{link}}.

\section{Team Members:}
1. Eashwar Sathyamurthy
2. Akwasi A Obeng
3. Achal P Vyas

\section{Difficulty faced:}
The RANSAC algorithm did not sample the points accurately. As a result, we got different values from the Opencv function. Due to large input data size, we ran the program for about half a day to get the output video.
\end{document}