Commit 483d18ef authored by Philipp Arras's avatar Philipp Arras
Browse files

texttt -> lstinline

parent f4d88ab7
Pipeline #79999 passed with stage
in 32 seconds
......@@ -102,10 +102,10 @@ in a fashion which is compatible with our inference machinery called NIFTy.
fit your needs better.
\item The explanations below shall be pretty general in order to be applicable
to a variety of problems. Therefore, the text might be difficult to understand
in its full generality. However, it is not unlikely that your \texttt{R}
in its full generality. However, it is not unlikely that your \lstinline{R}
(which will be defined below) is just a linear function. In this case
everything becomes very simple, since the derivative of a linear function is
just the function itself. Then only \texttt{R(s)} and \texttt{R\_adjoint(d)}
just the function itself. Then only \lstinline{R(s)} and \lstinline{R_adjoint(d)}
need to be implemented. You do not need to understand what I'm saying already
at this point. Just feel lucky and relax. You may relax anyways.
\item Read the full guide before you start implementing something.
......@@ -142,24 +142,24 @@ Since NIFTy is implemented in Python and is based on numpy let us be as specific
as possible and talk about numpy arrays. In the end, $s$ and $d$ will be numpy
arrays.
The array \texttt{d} is created by a script which reads in the actual data which
The array \lstinline{d} is created by a script which reads in the actual data which
drops out of an instrument. This array will remain constant throughout the IFT
algorithm since the data is given and never will be changed.
The array \texttt{s} is obviously not constant; only its shape won't change in
the course of the algorithm. In \texttt{s}, NIFTy will store the reconstruction
of the physical field which the user wants to infer. \texttt{s} would be a
The array \lstinline{s} is obviously not constant; only its shape won't change in
the course of the algorithm. In \lstinline{s}, NIFTy will store the reconstruction
of the physical field which the user wants to infer. \lstinline{s} would be a
one-dimensional array for a time-series, two-dimensional for a multi-frequency
time-series or for a single-frequency image of the sky, three-dimensional for a
multi-frequency image of the sky, etc. To cut a long story short: be aware of the
shape of \texttt{s} and \texttt{d}!
shape of \lstinline{s} and \lstinline{d}!
\subsection*{The response}
When we talk about \enquote{the response}, we mean a function \texttt{R(s)} which
takes an array of shape \texttt{s.shape} and returns an array of shape
\texttt{d.shape}. This function shall be made such that it simulates the
measurement device. Assume one knows the signal \texttt{s}, what would be the
data \texttt{d} in a noiseless measurement? Make sure that you understand what a
When we talk about \enquote{the response}, we mean a function \lstinline{R(s)} which
takes an array of shape \lstinline{s.shape} and returns an array of shape
\lstinline{d.shape}. This function shall be made such that it simulates the
measurement device. Assume one knows the signal \lstinline{s}, what would be the
data \lstinline{d} in a noiseless measurement? Make sure that you understand what a
response is to 100\%. If you have questions about it, do not hesitate to ask!
This is one of the crucial parts of the whole process. The following code shall
be running.
......@@ -184,32 +184,32 @@ function:
\begin{align*}
R: \mathbb R^{s.shape} \to \mathbb R^{d.shape},
\end{align*}
its gradient at the position \texttt{s=position} is a linear map of the
its gradient at the position \lstinline{s=position} is a linear map of the
following shape: \footnote{There are various ways to think about derivatives and
gradients of multi-dimensional functions. A different view on gradients would
be that at a given point $s=\text{position}$ the gradient is a matrix with
\texttt{s.size} columns and \texttt{d.size} rows. Obviously, it is not
\lstinline{s.size} columns and \lstinline{d.size} rows. Obviously, it is not
feasible to store such a matrix on a computer due to its size. Therefore we think
of this matrix in terms of a linear map which maps an array of shape
\texttt{s.shape} to an array of shape \texttt{d.shape}. This linear map shall
\lstinline{s.shape} to an array of shape \lstinline{d.shape}. This linear map shall
be implemented on the computer in terms of a function. Think of this map as a
linear approximation to \texttt{R} based at \texttt{position}.}
linear approximation to \lstinline{R} based at \lstinline{position}.}
\begin{align*}
\left. \frac{dR}{ds}\right|_{s=\text{position}} = R': \mathbb R^{s.shape} \to \mathbb R^{d.shape}
\end{align*}
What needs to be implemented is a function \texttt{R\_prime(position, s0)} which
takes the arguments \texttt{position} (which is an array of shape \texttt{s.shape}
What needs to be implemented is a function \lstinline{R_prime(position, s0)} which
takes the arguments \lstinline{position} (which is an array of shape \lstinline{s.shape}
and determines the position at which we want to calculate the derivative) and
the array \texttt{s0} of which the derivative shall be taken.
\texttt{R\_prime} is nonlinear in \texttt{position} in general and linear in
\texttt{s0}. The output of \texttt{R\_prime} is of shape \texttt{d.shape}.
the array \lstinline{s0} of which the derivative shall be taken.
\lstinline{R_prime} is nonlinear in \lstinline{position} in general and linear in
\lstinline{s0}. The output of \lstinline{R_prime} is of shape \lstinline{d.shape}.
Finally, we need to implement the function \texttt{R\_prime\_adjoint(postition, d0)}.
Finally, we need to implement the function \lstinline{R_prime_adjoint(postition, d0)}.
It implements the adjoint action of the derivative: $R'^\dagger$. It takes
a \texttt{position} of shape \texttt{s.shape} as well. After the position is set
a \lstinline{position} of shape \lstinline{s.shape} as well. After the position is set
we've got a linear function again which shall be the adjoint to
\texttt{R\_prime(position, \_)}. Thus, \texttt{d0} has the same shape as the data
\texttt{d} and the output of \texttt{R\_prime} has the shape \texttt{s.shape}.
\lstinline{R_prime(position, _)}. Thus, \lstinline{d0} has the same shape as the data
\lstinline{d} and the output of \lstinline{R_prime} has the shape \lstinline{s.shape}.
In order to test your implementation make sure that the following code runs
through:
......@@ -238,7 +238,7 @@ np.testing.assert_allclose(finite_diff, derivative)
\section*{The same in NIFTy language}
You might have noticed that you needed to use the size of a pixel in signal
space in order to implement your response. This pixel size will change as soon
as we change the resolution of our reconstruction \texttt{s}. And this is where
as we change the resolution of our reconstruction \lstinline{s}. And this is where
NIFTy comes in. NIFTy has the notion of \enquote{spaces}. In a nutshell, a NIFTy
space comes with the following properties:
......@@ -255,31 +255,31 @@ space comes with the following properties:
\end{itemize}
What needs to be done now, is to make the three functions which were implemented
above (\texttt{R(s)}, \texttt{R\_prime(position, s)} and
\texttt{R\_prime\_adjoint(position, d)}) aware of the space on which
\texttt{position}, \texttt{s} (these are the same) and \texttt{d} are defined.
above (\lstinline{R(s)}, \lstinline{R_prime(position, s)} and
\lstinline{R_prime_adjoint(position, d)}) aware of the space on which
\lstinline{position}, \lstinline{s} (these are the same) and \lstinline{d} are defined.
\subsection*{Derivative of response}
To this end, define your own class \texttt{DerivativeResponse} which inherits
from the NIFTy class \texttt{LinearOperator}. I recommend to take a simple
linear operator like the \texttt{FieldZeroPadder}, copy it and adopt it to your
needs. The method \texttt{apply()} takes an instance of \texttt{Field} (which is
To this end, define your own class \lstinline{DerivativeResponse} which inherits
from the NIFTy class \lstinline{LinearOperator}. I recommend to take a simple
linear operator like the \lstinline{FieldZeroPadder}, copy it and adopt it to your
needs. The method \lstinline{apply()} takes an instance of \lstinline{Field} (which is
esentially a numpy array accompanied by a domain) and returns one as well.
Some tips exclusively for you:
\begin{itemize}
\item Please have a look at the method \texttt{weight()} of \texttt{Field}. With
\item Please have a look at the method \lstinline{weight()} of \lstinline{Field}. With
it, you can easily multiply the field values with or divide by the volume of
each pixel.
\item The methods \texttt{from\_raw()} and \texttt{val()}
\item The methods \lstinline{from_raw()} and \lstinline{val()}
convert a Field to a numpy array and vice versa.
\item Be aware of the fact that NIFTy fields are immutable. As soon as you
pass a numpy array into a NIFTy field with \texttt{from\_raw()}, the
pass a numpy array into a NIFTy field with \lstinline{from_raw()}, the
\enquote{lock} flag will be set and the numpy array is immutable
afterwards. \texttt{val()} returns an object reference to this
afterwards. \lstinline{val()} returns an object reference to this
numpy array which is locked and cannot be modified. If you want to modify
it, you may want to obtain an unlocked copy via
\texttt{val\_rw()}.
\lstinline{val_rw()}.
\end{itemize}
The point is: You need to fiddle around until the following test passes:
......@@ -292,8 +292,8 @@ This test does the same as the test for the adjointness above.
\subsection*{Response}
So far, we have wrapped the derivative of the response in a
\texttt{LinearOperator}. The other thing to be done is to make the function
\texttt{R(s)} field-aware. Rewrite it such that it takes a field in signal space
\lstinline{LinearOperator}. The other thing to be done is to make the function
\lstinline{R(s)} field-aware. Rewrite it such that it takes a field in signal space
as input and returns a field in data space. Make sure that all methods you have
implemented can deal with arbitrary sizes of the signal space. All pixel volumes
should be taken care of by you.
......@@ -303,9 +303,9 @@ The information a $\gamma$-ray astronomer would provide to the algorithm (in the
simplest case):
\begin{itemize}
\item Data has Poissonian statistics.
\item Two functions: \texttt{R(s)} and \texttt{R\_adjoint(d)} where $R$ applies a convolution with
a Gaussian kernel of given size to \texttt{s} and picks out the positions to which
there exists a data point in \texttt{d}. \texttt{R\_adjoint(d)} implements $R^\dagger$.
\item Two functions: \lstinline{R(s)} and \lstinline{R_adjoint(d)} where $R$ applies a convolution with
a Gaussian kernel of given size to \lstinline{s} and picks out the positions to which
there exists a data point in \lstinline{d}. \lstinline{R_adjoint(d)} implements $R^\dagger$.
\end{itemize}
Why is this already sufficient?
\begin{itemize}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment