```python
print "hello world"
```

    hello world

## large cells

```python
# simple code
2 + 2
```

    4

```python
# simple variable
x = 3

# print it
print x
```

    3

```python
# a function
def print_hello(name) :
    print 'hello {0}'.format(name)
```

```python
print_hello("bro")
```

    hello bro

# help key board short cuts to find all the keyboard short cut, esc + l print line numbers

```python
!python --version

```

    Python 2.7.15 :: Anaconda, Inc.

```python
%matplotlib inline
```

```python
import matplotlib.pyplot as plt
plt.plot(range(100))
```

matplotlib helps you plot stuff on the jupyther notebook

```python
%time x = range(10000)
```

    Wall time: 1 ms

## time your functions with time

```python
%%timeit x = range(10000)
max(x)
```

    1000 loops, best of 3: 221 µs per loop

# writes to files

```python
%%writefile test.txt
this is some stuff that i wrote form jupiter notebook
```

    Writing test.txt

# ls list directory

```python
%ls

```

     Volume in drive F has no label.
     Volume Serial Number is C816-9EA8

     Directory of F:\anacondaWD

    23-Jul-18  00:19    <DIR>          .
    23-Jul-18  00:19    <DIR>          ..
    23-Jul-18  00:00    <DIR>          .ipynb_checkpoints
    23-Jul-18  00:19            16,013 My First Notebook.ipynb
    23-Jul-18  00:18                54 test.txt
                   2 File(s)         16,067 bytes
                   3 Dir(s)  528,140,967,936 bytes free

# we can use latex in jupyter with %latex

```latex
%%latex
\begin{align}
Gradient: \nabla J = -2H^T (Y -HW)
\end{align}
```

\begin{align}
Gradient: \nabla J = -2H^T (Y -HW)
\end{align}

## load_ext loads extensions

```python
%%!
pip install ipython-sql

```

    ['Collecting ipython-sql',
     '  Downloading https://files.pythonhosted.org/packages/ab/df/427e7cf05ffc67e78672ad57dce2436c1e825129033effe6fcaf804d0c60/ipython_sql-0.3.9-py2.py3-none-any.whl',
     'Collecting sqlparse (from ipython-sql)',
     '  Downloading https://files.pythonhosted.org/packages/65/85/20bdd72f4537cf2c4d5d005368d502b2f464ede22982e724a82c86268eda/sqlparse-0.2.4-py2.py3-none-any.whl',
     'Requirement already satisfied: ipython-genutils>=0.1.0 in f:\\anaconda\\lib\\site-packages (from ipython-sql) (0.2.0)',
     'Requirement already satisfied: ipython>=1.0 in f:\\anaconda\\lib\\site-packages (from ipython-sql) (5.7.0)',
     'Requirement already satisfied: six in f:\\anaconda\\lib\\site-packages (from ipython-sql) (1.11.0)',
     'Requirement already satisfied: sqlalchemy>=0.6.7 in f:\\anaconda\\lib\\site-packages (from ipython-sql) (1.2.7)',
     'Collecting prettytable (from ipython-sql)',
     '  Downloading https://files.pythonhosted.org/packages/ef/30/4b0746848746ed5941f052479e7c23d2b56d174b82f4fd34a25e389831f5/prettytable-0.7.2.tar.bz2',
     'Requirement already satisfied: prompt-toolkit<2.0.0,>=1.0.4 in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (1.0.15)',
     'Requirement already satisfied: setuptools>=18.5 in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (39.1.0)',
     'Requirement already satisfied: decorator in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (4.3.0)',
     'Requirement already satisfied: pickleshare in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (0.7.4)',
     'Requirement already satisfied: win-unicode-console>=0.5; sys_platform == "win32" and python_version < "3.6" in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (0.5)',
     'Requirement already satisfied: pygments in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (2.2.0)',
     'Requirement already satisfied: pathlib2; python_version == "2.7" or python_version == "3.3" in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (2.3.2)',
     'Requirement already satisfied: backports.shutil-get-terminal-size; python_version == "2.7" in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (1.0.0)',
     'Requirement already satisfied: colorama; sys_platform == "win32" in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (0.3.9)',
     'Requirement already satisfied: simplegeneric>0.8 in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (0.8.1)',
     'Requirement already satisfied: traitlets>=4.2 in f:\\anaconda\\lib\\site-packages (from ipython>=1.0->ipython-sql) (4.3.2)',
     'Requirement already satisfied: wcwidth in f:\\anaconda\\lib\\site-packages (from prompt-toolkit<2.0.0,>=1.0.4->ipython>=1.0->ipython-sql) (0.1.7)',
     'Requirement already satisfied: scandir in f:\\anaconda\\lib\\site-packages (from pathlib2; python_version == "2.7" or python_version == "3.3"->ipython>=1.0->ipython-sql) (1.7)',
     'Requirement already satisfied: enum34 in f:\\anaconda\\lib\\site-packages (from traitlets>=4.2->ipython>=1.0->ipython-sql) (1.1.6)',
     'Building wheels for collected packages: prettytable',
     '  Running setup.py bdist_wheel for prettytable: started',
     "  Running setup.py bdist_wheel for prettytable: finished with status 'done'",
     '  Stored in directory: C:\\Users\\home\\AppData\\Local\\pip\\Cache\\wheels\\80\\34\\1c\\3967380d9676d162cb59513bd9dc862d0584e045a162095606',
     'Successfully built prettytable',
     'distributed 1.21.8 requires msgpack, which is not installed.',
     'grin 1.2.1 requires argparse>=1.1, which is not installed.',
     'Installing collected packages: sqlparse, prettytable, ipython-sql',
     'Successfully installed ipython-sql-0.3.9 prettytable-0.7.2 sqlparse-0.2.4',
     'You are using pip version 10.0.1, however version 18.0 is available.',
     "You should consider upgrading via the 'python -m pip install --upgrade pip' command."]

```python
%load_ext sql

```

```python
%sql sqlite://
```

    'Connected: @None'

```sql
%%sql
create table classT(name, age, marks);
insert into classT values("bob", 22, 99);
insert into classT values("tom", 21, 88);
```

     * sqlite://
    Done.
    1 rows affected.
    1 rows affected.

    []

```python
%sql select * from classT;
```

     * sqlite://
    Done.

        name
        age
        marks

        bob
        22
        99

        tom
        21
        88

# List all of the magic functions %lsmagic

```python
%lsmagic
```

    Available line magics:
    %alias  %alias_magic  %autocall  %automagic  %autosave  %bookmark  %cd  %clear  %cls  %colors  %config  %connect_info  %copy  %ddir  %debug  %dhist  %dirs  %doctest_mode  %echo  %ed  %edit  %env  %gui  %hist  %history  %killbgscripts  %ldir  %less  %load  %load_ext  %loadpy  %logoff  %logon  %logstart  %logstate  %logstop  %ls  %lsmagic  %macro  %magic  %matplotlib  %mkdir  %more  %notebook  %page  %pastebin  %pdb  %pdef  %pdoc  %pfile  %pinfo  %pinfo2  %popd  %pprint  %precision  %profile  %prun  %psearch  %psource  %pushd  %pwd  %pycat  %pylab  %qtconsole  %quickref  %recall  %rehashx  %reload_ext  %ren  %rep  %rerun  %reset  %reset_selective  %rmdir  %run  %save  %sc  %set_env  %sql  %store  %sx  %system  %tb  %time  %timeit  %unalias  %unload_ext  %who  %who_ls  %whos  %xdel  %xmode

    Available cell magics:
    %%!  %%HTML  %%SVG  %%bash  %%capture  %%cmd  %%debug  %%file  %%html  %%javascript  %%js  %%latex  %%perl  %%prun  %%pypy  %%python  %%python2  %%python3  %%ruby  %%script  %%sh  %%sql  %%svg  %%sx  %%system  %%time  %%timeit  %%writefile

    Automagic is ON, % prefix IS NOT needed for line magics.

```python
import sklearn.tree

help(sklearn.tree._tree.Tree)
```

    Help on class Tree in module sklearn.tree._tree:

    class Tree(__builtin__.object)
     |  Array-based representation of a binary decision tree.
     |
     |  The binary tree is represented as a number of parallel arrays. The i-th
     |  element of each array holds information about the node `i`. Node 0 is the
     |  tree's root. You can find a detailed description of all arrays in
     |  `_tree.pxd`. NOTE: Some of the arrays only apply to either leaves or split
     |  nodes, resp. In this case the values of nodes of the other type are
     |  arbitrary!
     |
     |  Attributes
     |  ----------
     |  node_count : int
     |      The number of nodes (internal nodes + leaves) in the tree.
     |
     |  capacity : int
     |      The current capacity (i.e., size) of the arrays, which is at least as
     |      great as `node_count`.
     |
     |  max_depth : int
     |      The maximal depth of the tree.
     |
     |  children_left : array of int, shape [node_count]
     |      children_left[i] holds the node id of the left child of node i.
     |      For leaves, children_left[i] == TREE_LEAF. Otherwise,
     |      children_left[i] > i. This child handles the case where
     |      X[:, feature[i]] <= threshold[i].
     |
     |  children_right : array of int, shape [node_count]
     |      children_right[i] holds the node id of the right child of node i.
     |      For leaves, children_right[i] == TREE_LEAF. Otherwise,
     |      children_right[i] > i. This child handles the case where
     |      X[:, feature[i]] > threshold[i].
     |
     |  feature : array of int, shape [node_count]
     |      feature[i] holds the feature to split on, for the internal node i.
     |
     |  threshold : array of double, shape [node_count]
     |      threshold[i] holds the threshold for the internal node i.
     |
     |  value : array of double, shape [node_count, n_outputs, max_n_classes]
     |      Contains the constant prediction value of each node.
     |
     |  impurity : array of double, shape [node_count]
     |      impurity[i] holds the impurity (i.e., the value of the splitting
     |      criterion) at node i.
     |
     |  n_node_samples : array of int, shape [node_count]
     |      n_node_samples[i] holds the number of training samples reaching node i.
     |
     |  weighted_n_node_samples : array of int, shape [node_count]
     |      weighted_n_node_samples[i] holds the weighted number of training samples
     |      reaching node i.
     |
     |  Methods defined here:
     |
     |  __getstate__(...)
     |      Getstate re-implementation, for pickling.
     |
     |  __reduce__(...)
     |      Reduce re-implementation, for pickling.
     |
     |  __setstate__(...)
     |      Setstate re-implementation, for unpickling.
     |
     |  apply(...)
     |      Finds the terminal region (=leaf node) for each sample in X.
     |
     |  compute_feature_importances(...)
     |      Computes the importance of each feature (aka variable).
     |
     |  decision_path(...)
     |      Finds the decision path (=node) for each sample in X.
     |
     |  predict(...)
     |      Predict target for X.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  capacity
     |
     |  children_left
     |
     |  children_right
     |
     |  feature
     |
     |  impurity
     |
     |  max_depth
     |
     |  max_n_classes
     |
     |  n_classes
     |
     |  n_features
     |
     |  n_node_samples
     |
     |  n_outputs
     |
     |  node_count
     |
     |  threshold
     |
     |  value
     |
     |  weighted_n_node_samples
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __new__ = <built-in method __new__ of type object>
     |      T.__new__(S, ...) -> a new object with type S, a subtype of T
     |
     |  __pyx_vtable__ = <capsule object NULL>

```python

```


```python
from IPython.core.display import display_html
from urllib.request import urlopen

cssurl = 'http://j.mp/1DnuN9M'
display_html(urlopen(cssurl).read(), raw=True)
```

<link href='http://fonts.googleapis.com/css?family=EB+Garamond' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Lato:100,100italic' rel='stylesheet' type='text/css'>

<style>
	@font-face{
   		font-family: "Computer Modern";
        	src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');}

        div.cell{
	        max-width:    800px;
	        margin-left:  auto;
	        margin-right: auto;}

	h1 {
        	font-family: 'Lato', sans-serif;}

	h2 {
        	font-family: 'Lato', serif;}

	h3{
		font-family:   'Lato', serif;
        	margin-top:    12px;
		margin-bottom: 3px;}

        h4{
		font-family: 'Lato', serif;}

	h5 {
        	font-family: 'Lato', serif;}

	div.text_cell_render{
        	font-family:  'EB Garamond', 'Computer Modern', 'Helvetica Neue', Arial, Helvetica, Geneva, sans-serif;
	        line-height:  140%;
	        font-size:    14pt;
		max-width:    650px;
		margin-left:  auto;
        	margin-right: auto;}

	.CodeMirror{
        	font-family: 'Consolas';}

	.text_cell_render h1 {
	        font-weight:   100;
	        font-size:     48pt;
		line-height:   100%;
	        color:         #CD2305;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.text_cell_render h2 {
        	font-weight:   100;
        	font-size:     36pt;}

	.text_cell_render h3 {
        	font-weight:   100;
        	font-size:     21pt;}

	.text_cell_render h4 {
        	font-weight:   100;
        	font-size:     18pt;}

	.text_cell_render h5 {
	        font-weight:   100;
	        font-size:     16pt;
	        color:         #CD2305;
	        font-style:    italic;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.text_cell_render h6 {
	        font-weight:   100;
	        font-size:     14pt;
	        color:         #CD2305;
	        font-style:    italic;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.warning{
	    	background-color: #FFFFE0;
	    	border-color: #FFCC99;
	    	border-left: 5px solid #FFCC99;
	    	padding: 0.5em;}

	.error{
	    	background-color: #fcf2f2;
	    	border-color: #dFb5b4;
	    	border-left: 5px solid #dfb5b4;
	    	padding: 0.5em;}

</style>

# Tarea 6

## Simulación de un sistema con retardo por medio de la construcción de una Matriz de Lyapunov

Dado el sistema:

$$
\dot{x}(t) = A_0 x(t) + A_1 x(t - \tau)
$$

proponemos una solución de la forma $x(t) = U(\tau)$ con $U(\tau)$ de la forma:

$$
U(\tau) = \int_0^{\infty} K^T(t) W K(t + \tau) dt
$$

Solución que sabemos satisface la condición dinámica del sistema:

$$
\frac{d U(\tau)}{d \tau} = U(\tau) A_0 + U(\tau - h) A_1
$$

la cual, para un tiempo negativo sería:

$$
\frac{d U(- \tau)}{d \tau} = U(- \tau) A_0 + U(- \tau - h) A_1
$$

asi como la propiedad simetrica:

$$
U(-\tau) = U^T(\tau) \quad \tau \geq 0
$$

por lo que tenemos que la propiedad dinámica del sistema queda:

$$
\frac{d U(\tau)}{d \tau} = -A_0^T U(\tau) - A_1^T U(\tau + h)
$$

o bien:

$$
\frac{d U(\tau - h)}{d \tau} = -A_0^T U(\tau - h) - A_1^T U(\tau)
$$

En este punto introducimos dos variables auxiliares, $Y(\tau) = U(\tau)$ y $Z(\tau) = U(\tau - h)$, para expresar la condición dinámica del sistema y esta ultiima expresión en forma de un sistema acoplado:

$$
\frac{d Y(\tau)}{d \tau} = Y(\tau) A_0 + Z(\tau) A_1
$$

$$
\frac{d Z(\tau)}{d \tau} = -A_1^T Y(\tau) - A_0^T Z(\tau)
$$

en donde notamos que tenemos un sistema sin retardos explicitos, por lo que podemos utilizar tecnicas convencionales para el analisis de este sistema, mas aun, podemos construir una matriz que de el comportamiento de este sistema acoplado.

Para poder lograr esto, primero tenemos que hablar de la vectorización de una matriz y del producto de Kronecker; dada una matriz $A$ de la forma:

$$
A =
\begin{pmatrix}
a_1 & a_2 & \dots & a_n
\end{pmatrix}
$$

en donde $a_1, a_2, \dots, a_n$ son las columnas de $A$ definimos la vectorización de $A$ como:

<div style="display:none">
  $\DeclareMathOperator{\vect}{vec}$
</div>

$$
\vect{(A)} =
\begin{pmatrix}
a_1 \\
a_2 \\
\vdots \\
a_n
\end{pmatrix}
$$

es decir, un vector en donde todas las columnas se colocan consecutivamente en la primera.

Dada esta definición, podemos decir que una manera de simplificar la vectorización de un producto es:

$$
\vect{(AXB)} = (B^T \otimes A) \vect{(X)}
$$

en donde $\otimes$ es el producto de Kronecker y se define como:

$$
A \otimes B =
\begin{pmatrix}
a_{11} B & a_{12} B & \dots & a_{1n} B \\
a_{21} B & a_{22} B & \dots & a_{2n} B \\
\vdots & \vdots & & \vdots \\
a_{n1} B & a_{n2} B & \dots & a_{nn} B \\
\end{pmatrix}
$$

El sistema acoplado que obtuvimos es equivalente a:

$$
\frac{d Y(\tau)}{d \tau} = I Y(\tau) A_0 + I Z(\tau) A_1
$$

$$
\frac{d Z(\tau)}{d \tau} = -A_1^T Y(\tau) I - A_0^T Z(\tau) I
$$

por lo que al vectorizar estas expresiones, obtendremos:

$$
\frac{d \bar{Y}(\tau)}{d \tau} = \left( A_0^T \otimes I \right) \bar{Y}(\tau) + \left( A_1^T \otimes I \right) \bar{Z}(\tau)
$$

$$
\frac{d \bar{Z}(\tau)}{d \tau} = - \left( I \otimes A_1^T \right) \bar{Y}(\tau) - \left( I \otimes A_0^T \right) \bar{Z}(\tau)
$$

o bien:

$$
\frac{d}{d\tau}
\begin{pmatrix}
\bar{Y}(\tau) \\
\bar{Z}(\tau)
\end{pmatrix} =
\begin{pmatrix}
A_0^T \otimes I & A_1^T \otimes I \\
-I \otimes A_1^T & -I \otimes A_0^T
\end{pmatrix}
\begin{pmatrix}
\bar{Y}(\tau) \\
\bar{Z}(\tau)
\end{pmatrix}
$$

lo que sugiere una solución de la forma:

$$
\begin{pmatrix}
\bar{Y}(\tau) \\
\bar{Z}(\tau)
\end{pmatrix} = e^{L \tau}
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix}
$$

en donde $L$ es la matriz de Lyapunov, de la forma:

$$
L =
\begin{pmatrix}
A_0^T \otimes I & A_1^T \otimes I \\
-I \otimes A_1^T & -I \otimes A_0^T
\end{pmatrix}
$$

Ahora consideremos las condiciones iniciales, asi como la propiedad algebraica del sistema:

$$
U(0) A_0 + U(-h) A_1 + A_0^T U(0) + A_1^T U(h) = -W
$$

notando que las condiciones iniciales para $U$ se traducen en:

$$
Y(0) = U(0) \quad Z(0) = U(-h) \quad Y(h) = U(h)
$$

podemos reescribir esta propiedad como:

$$
Y(0) A_0 + Z(0) A_1 + A_0^T Y(0) + A_1^T Y(h) = -W
$$

vectorizando, esto nos queda:

$$
\left( A_0^T \otimes I \right) \bar{Y}(0) + \left( A_1^T \otimes I \right) \bar{Z}(0) + \left( I \otimes A_0^T \right) \bar{Y}(0) + \left( I \otimes A_1^T \right) \bar{Y}(h) = -\bar{W}
$$

A esta ecuación le agregamos la vectorización de una condición inicial dada ya:

$$
\bar{Y}(h) - \bar{Z}(h) = \bar{0}
$$

y tenemos que este sistema acoplado puede ser escrito como:

$$
\begin{align}
\begin{pmatrix}
A_0^T \otimes I + I \otimes A_0^T & A_1^T \otimes I \\
I \otimes I & 0 \otimes 0
\end{pmatrix}
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix} &+ \\
\begin{pmatrix}
I \otimes A_1^T & 0 \otimes 0 \\
0 \otimes 0 & -I \otimes I
\end{pmatrix}
\begin{pmatrix}
\bar{Y}(h) \\
\bar{Z}(h)
\end{pmatrix} &=
\begin{pmatrix}
- \bar{W} \\
\bar{0}
\end{pmatrix}
\end{align}
$$

o bien:

$$
M
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix} + N
\begin{pmatrix}
\bar{Y}(h) \\
\bar{Z}(h)
\end{pmatrix} =
\begin{pmatrix}
- \bar{W} \\
\bar{0}
\end{pmatrix}
$$

con

$$
M =
\begin{pmatrix}
A_0^T \otimes I + I \otimes A_0^T & A_1^T \otimes I \\
I \otimes I & 0 \otimes 0
\end{pmatrix}
$$

$$
N =
\begin{pmatrix}
I \otimes A_1^T & 0 \otimes 0 \\
0 \otimes 0 & -I \otimes I
\end{pmatrix}
$$

aun más, vemos que el termino $\begin{pmatrix} \bar{Y}(h) \\ \bar{Z}(h) \end{pmatrix}$ se puede obtener con el resultado anterior:

$$
\begin{pmatrix}
\bar{Y}(h) \\
\bar{Z}(h)
\end{pmatrix} = e^{L h}
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix}
$$

por lo que al sustituir en esta expresión, tenemos:

$$
M
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix} + N e^{L h}
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix} =
\begin{pmatrix}
- \bar{W} \\
\bar{0}
\end{pmatrix}
$$

$$
\left( M + N e^{L h} \right)
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix} =
\begin{pmatrix}
- \bar{W} \\
\bar{0}
\end{pmatrix}
$$

$$
\begin{pmatrix}
\bar{Y}(0) \\
\bar{Z}(0)
\end{pmatrix} =
\left( M + N e^{L h} \right)^{-1}
\begin{pmatrix}
- \bar{W} \\
\bar{0}
\end{pmatrix}
$$

Esta expresión la podemos sustituir en la original y obtener:

$$
\begin{pmatrix}
\bar{Y}(\tau) \\
\bar{Z}(\tau)
\end{pmatrix} = e^{L \tau} \left( M + N e^{L h} \right)^{-1}
\begin{pmatrix}
- \bar{W} \\
\bar{0}
\end{pmatrix}
$$

Para esta simulación utilizaremos los siguientes valores:

$$
A_0 =
\begin{pmatrix}
0 & 1 \\
-1 & 0
\end{pmatrix} \quad
A_1 =
\begin{pmatrix}
-2 & 0 \\
0.3 & 0
\end{pmatrix} \quad W = I \quad \tau \in [0, 1]
$$

Declaramos estas matrices, asi como una matriz de ceros, la identidad y las vectorizaciones de una matriz de ceros, asi como la de la matriz $W$.

```python
from numpy import array, matrix, kron, eye, zeros, vstack, hstack, linspace
from scipy.linalg import expm
```

```python
A0 = matrix([[0, 1], [-1, 0]])
A0
```

    matrix([[ 0,  1],
            [-1,  0]])

```python
A1 = matrix([[-2, 0], [0.3, 0]])
A1
```

    matrix([[-2. ,  0. ],
            [ 0.3,  0. ]])

```python
I = matrix(eye(2))
I
```

    matrix([[ 1.,  0.],
            [ 0.,  1.]])

```python
cero = zeros((2**2, 2**2))
cero
```

    array([[ 0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.]])

```python
v0 = matrix(zeros(4))
v0
```

    matrix([[ 0.,  0.,  0.,  0.]])

```python
W = I
W.flatten("F")
```

    matrix([[ 1.,  0.,  0.,  1.]])

Ahora calculamos la matriz de Lyapunov, asi como las matrices $M$ y $N$

```python
L = vstack((hstack((kron(A0.T, I), kron(A1.T, I))),
        hstack((kron(-I, A1.T), kron(-I, A0.T)))))
L
```

    matrix([[ 0. ,  0. , -1. , -0. , -2. , -0. ,  0.3,  0. ],
            [ 0. ,  0. , -0. , -1. , -0. , -2. ,  0. ,  0.3],
            [ 1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 2. , -0.3,  0. , -0. , -0. ,  1. , -0. ,  0. ],
            [-0. , -0. , -0. , -0. , -1. , -0. , -0. , -0. ],
            [ 0. , -0. ,  2. , -0.3, -0. ,  0. , -0. ,  1. ],
            [-0. , -0. , -0. , -0. , -0. , -0. , -1. , -0. ]])

```python
M = vstack((hstack((kron(A0.T, I) + kron(I, A0.T), kron(A1.T, I))),
            hstack((kron(I, I), cero))))
M
```

    matrix([[ 0. , -1. , -1. , -0. , -2. , -0. ,  0.3,  0. ],
            [ 1. ,  0. ,  0. , -1. , -0. , -2. ,  0. ,  0.3],
            [ 1. ,  0. ,  0. , -1. ,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  1. ,  1. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  0. ,  1. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  0. ,  0. ,  1. ,  0. ,  0. ,  0. ,  0. ]])

```python
N = vstack((hstack((kron(I, A1.T), cero)),
            hstack((cero, kron(-I, I)))))
N
```

    matrix([[-2. ,  0.3, -0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [-0. ,  0. , -2. ,  0.3,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
            [ 0. ,  0. ,  0. ,  0. , -1. , -0. , -0. , -0. ],
            [ 0. ,  0. ,  0. ,  0. , -0. , -1. , -0. , -0. ],
            [ 0. ,  0. ,  0. ,  0. , -0. , -0. , -1. , -0. ],
            [ 0. ,  0. ,  0. ,  0. , -0. , -0. , -0. , -1. ]])

```python
v = vstack((- W.flatten("F").T, v0.T))
v
```

    matrix([[-1.],
            [-0.],
            [-0.],
            [-1.],
            [ 0.],
            [ 0.],
            [ 0.],
            [ 0.]])

Ahora declaramos la función $f(\tau)$ la cual es de la forma:

$$
f(\tau) := e^{L \tau} \left( M + N e^{L h} \right)^{-1}
\begin{pmatrix}
\bar{0} \\
\bar{W}
\end{pmatrix}
$$

con la que podremos calcular los valores de:

$$
\begin{pmatrix}
\bar{Y}(\tau) \\
\bar{Z}(\tau)
\end{pmatrix}
$$

para cada $\tau$ que le demos como argumento:

```python
h = 1
f = lambda tau: (expm(L*tau)*(M + N*expm(L*h)).I*v).flatten().tolist()[0]
```

utilizamos $h = \frac{1}{2}$ para probar nuestra función:

```python
# Fijamos la precision de los datos mostrados a 3 cifras significativas
# para facilitar la lectura

%precision 3
```

    u'%.3f'

```python
tau = 0.5
v1 = f(tau)
v1
```

    [-0.309, -0.127, -0.750, 1.018, -0.309, -0.750, -0.127, 1.018]

y para un incremento en el retardo de $\frac{1}{10}$, tenemos:

```python
v2 = f(tau + 0.1)
v2
```

    [-0.163, -0.051, -0.774, 1.009, -0.427, -0.713, -0.208, 1.035]

por lo que solo queda declarar el dominio de definición de los retardos:

$$
T = [0, 1]
$$

y obtener el conjunto de soluciones para cada retardo en el dominio definido:

$$
V_{sol}= \left\{ f(t) \mid t \in T \right\}
$$

```python
T = linspace(0, 1, 1000)
vsol = [f(t) for t in T]
```

```python
sol = zip(*vsol)
```

Ahora solo queda graficar la soluciónes contra los retardos del sistema.

```python
%matplotlib inline
from matplotlib.pyplot import plot, figure, style, legend
style.use("ggplot")
```

```python
fig = figure(figsize=(12, 6))

p1, = plot(T, sol[0])
p2, = plot(T, sol[1])
p3, = plot(T, sol[2])
p4, = plot(T, sol[3])

ax = fig.gca()
ax.set_ylabel(r"$Y(\tau)$", fontsize=20)
ax.set_xlabel(r"$\tau$", fontsize=20)

legend([p1, p2, p3, p4],
       [r"$y_{11}(\tau)$",
        r"$y_{21}(\tau)$",
        r"$y_{12}(\tau)$",
        r"$y_{22}(\tau)$"]);
```

Puedes acceder a este notebook a traves de la página

http://bit.ly/1CccnJ9

o escaneando el siguiente código:

```python
# Codigo para generar codigo :)
from qrcode import make
img = make("http://bit.ly/1CccnJ9")
img.save("codigos/codigo6.jpg")
```

IPythonNotebooks/Sistemas con retardo en la entrada/Tarea 6.ipynb


# Equity Valuation
## Valuation by Comparables
Purpose of  fundamental analysis: identify stocks that are mispriced relative to some measure of “true” value that can be derived from observable financial data.

$\odot$
True value can only be estimated.$\square$

In practice, stock analysts use models to estimate from **observable market data** and from the **financial statements of the firm and its *competitors***.

They look at the relationship between price and various determinants of value for similar firms and then extrapolate that relationship to the firm in question.
***
The SEC requires all public companies (except foreign companies and companies with less than 10 million dollars in assets and 500 shareholders) to file registration statements.

**market cap**: total market value or capitalization: $\text{share price} \times \text{ number of shares }$.

>**e.g.** figures to be referenced
>
1. General
  1. Price per share
  2. Common shares outstanding (billion)
  3. Market Capitalization
2. Last 12 months
  1. Sales
  2. EBITDA
  3. Net income
  4. Earning per share
3. Valuation
  1. Price/Book
  2. Price/Sales
  3. Price/Cash flow
  4. PEG
4. Profitability
  1. ROE
  2. ROA
  3. Operating profit margin
  4. Net profit margin

**book value**: The net worth of common equity according to a firm’s balance sheet.

And market value over book value can be used to compare with the industry average to find wheather it is underpriced if the ratio is lower than the industry average.

### Limitations of Book Value
Shareholders, the value of their stake is what is left over when the liabilities of the firm are subtracted from its assets.

Shareholders’ equity is this net worth.

***Limitation***: the values of both assets and liabilities recognized in financial statements base on **historical**, not **current values**.

Book values are based on original cost, market values measure current values of assets and liabilities.

The market value of the shareholders’ equity investment = *current values of all assets* - *liabilities*。
***
For a *floor value*, below which level the market price can never fall, **liquidation value** per share can be considered, that is: **Net amount that can be realized by selling the assets of a firm and paying off the debt.**

1. Stock price goes below that
2. A corporate raider would buy enough shares to gain control (as a takeover target 被收购)
3. Liquidate the firm
  - because the liquidation value exceeds the value of the business as a going concern.

***
Another measure is the **replacement cost (Cost to replace a firm’s assets)** of assets less liabilities.
1. The company's market value get far above the replacemet cost for long
2. Competitors enter the market
3. Competitive pressure would drive down the market value of all firms until they fell to replacement cost.

**Tobin’s q**: Ratio of market value of the firm to replacement cost.
> In the long run, the ratio of market price to replacement cost will tend toward $1$, but the evidence is that this ratio can differ significantly from 1 for very long periods of time.

Focusing on the balance sheet can give some useful information, but the analyst usually must turn to **expected future cash flows** for a *better* estimate.

## Intrinsic Value Versus Market Price
1. Assuming a one-year holding period
2. Let the expected dividend per share be $E(D_1)$
3. Let the current price of a share be $P_0$
4. Let the expected price at the end of a year be $E(P_1)$

The expected holding-period return is:

$$\text{Expected HPR} = E(r) = \frac{E(D_1) + [E(P_1) - P_0]} {P_0}$$

Here, $E(P_1)$ is the expectation today of the stock price one year from now. $E(r)$ is the stock’s expected holding-period return, which is the sum of the expected dividend yield, $E(D_1) /P_0$, and the expected rate of price appreciation, the capital gains yield, $[E(P_1) – P_0]/P_0$.
***
**Capital Asset Pricing Model (CAPM)**: when stock market prices are at *equilibrium levels*, the rate of return that investors can expect to earn on a security is

$$r_f + \beta[E(r_M) – r_f]:=k$$

where $\beta$ is the risk, $r_f$ and $E(r_M) – r_f$ are given, $r_f$ is the risk free rate, $r_M$ is the rate of return on the market portfolio. $k$ is called the required rate of return.

If a stock is priced correctly, then its *expected return* is its *required return*, $i.e.$, $\text{Expected HPR} = k$.
***
Another way to see this is to compare the intrinsic value of a share of stock to its market price.
**Intrinsic Value**: The present value of a firm’s expected future net cash flows discounted by the required rate of return.

$\odot$dividends and proceeds from the ultimate sale of the stock are included in the cash flow.$square$

$$\text{Intrinsic Value} = \frac{E(D_1) + E(P_1)} {1 + k}:=V_0$$

$E(D_1)$ and $E(P_1)$ are given and $k$ is the **discounted rate**, as an risk-adjusted interest rate.

$\odot$Whenever the intrinsic value, or the investor’s own estimate of what the stock is really worth, exceeds the market price, the stock is considered undervalued and a good investment.$square$

>**e.g.**
>
>For company ABC, $E(D_1)$, expected dividend per share is 4 dollar; $P_0$, current price of a share, is \$48; $E(P_1)$, expected price at the end of a year, is \$52, then we have
>
>$$\text{Expected HPR} = E(r) = \frac{E(D_1) + [E(P_1) - P_0]} {P_0} = \frac{4+[52-48]} {48} = 16.7\%$$
>
>After that we have $r_f = 6\%$, $E(r_M) - r_f = 5\%$, $\beta = 1.2$, so that the required rate of return is
>
>$$k = 6\% + 1.2 \times 5\% = 12\%$$
>
>which indicates that the rate of return the investor expects exceeds the required rate based on ABC’s risk by a margin of $16.7\% - 12\% = 4.7\%$.
>
>And the intrinsic value is
>
>$$V_0 = \frac{E(D_1) + E(P_1)} {1 + k} = \frac{\$4 + \$52} {1.12} = \$50$$
>
>In this situation, the *intrinsic value* is bigger than the *current stock value*, and the expected return is 12%. So it means there's a fair rate of return relative to its risk, it is a *positive-alpha* stock. And for investors following a *passive strategy*, they will hold more ABC's stock.
***
**Market capitalization rate**: The market-consensus estimate of the appropriate discount rate for a firm’s cash flows.

$\odot$ In market equilibrium, the current market price will reflect the intrinsic value estimates of *all* market participants. This means:
1. The individual investor whose $V_0$ estimate differs from the market price, $P_0$
2. They must disagree with some or all of the **market-consensus estimates市场一致预期** of $E(D_1)$, $E(P_1)$, or $k$.

And $k$, the required rate of return, its market-consensus estimate is **market capitalization rate**.

**Market capitalization rate**: The market-consensus estimate of the appropriate discount rate for a firm’s cash flows.

## Dividend Discount Models
### General
First we have:

$$V_0 = \frac{D_1 + P_1} {1 + k}$$

Here we use simpler notation that still express the expected value, $i.e.$, $D_1$ stand for $E(D_1)$, and so is $P_1$.

And this formula indicates that value today of a share of stock equals the the ratio of the quanity of the dividend in peiod one plus the sale price in period one all divided by the quantity one pluse the discount rate.

But $D_1$ is easily to predict given the historical data, not for $P_1$. So that we can use

$$V_1 = \frac{D_2 + P_2} {1 + k}$$

Then we assume the stock will be selling for its intrinsic value next year, then $V_1 = P_1$, so that

$$V_0 = \frac{D_1} {1 + k} + \frac{D_2 + P_2} {(1 + k)^2}$$

Generally if we hold this stock for $H$ years, then we have:

$$V_0 = \frac{D_1} {1 + k} + \frac{D_2} {(1 + k)^2} + \cdots + \frac{D_H + P_H} {(1 + k)^H}$$

$\odot$ This formular is similar to that of bond valuation formula, since bonds have coupons just like dividends but keep a certain value. The key differences in the case of stocks are the uncertainty of dividends, the lack of a fixed maturity date, and the unknown sales price at the horizon date. $\square$

**Dividend discount model (DDM)**: A formula for the intrinsic value of a firm equal to the present value of all expected future dividends.

$$V_0 = \frac{D_1} {1 + k} + \frac{D_2} {(1 + k)^2} + \frac{D_3} {(1 + k)^3} + \cdots$$
### The Constant-Growth DDM
assume that dividends are trending upward at a stable growth rate, $g$, then we have

$$V_0 = \frac{D_0(1+g)} {1 + k} + \frac{D_0(1+g)^2} {(1 + k)^2} + \frac{D_0(1+g)^3} {(1 + k)^3} + \cdots$$

Then to make it converge, we assume that  $|(1+g)/(1+k)|<1$ so that we have

$$V_0 = \frac{D_0(1+g)} {k - g} = \frac{D_\mathbf{1}} {k - g}$$

**Constant-growth DDM**: A form of the dividend discount model that assumes dividends will grow at a constant rate.

Also known as the **Gordon model**.

>**e.g.**
>
>Preferred stock that pays a **fixed dividend**, so that $g = 0$.

$\odot$ The constant-growth DDM is valid only when g is less than k. If an analyst derives an estimate of g that is greater than k, that growth rate must be *unsustainable* in the *long run*.$\square$

### Implications and limitations
A stock’s value will be greater
1. The larger its expected dividend ($D_i$) per share.
2. The lower the market capitalization rate, $k$.
3. The higher the expected growth rate ($g$) of dividends.
***
Assume that stock is selling at its intrinsic value so that $P_i = V_i$, then

$$P_0 = V_0, P_1 = \frac{D_1 (1+g)} {k-g} = \frac{D_1} {k-g} (1+g) = P_0 (1+g)$$

Therefore, in the case of **constant expected growth of dividends**, the *expected rate of price appreciation* in any year will equal that *constant growth rate*, $g$. $\odot$ The stock price is expected to grow at the same rate as dividends.$\square$

So that for a stock whose market price equals its intrinsic value ($V_0 = P_0$), the expected holding-period return will be

$$E(r) = \text{Dividend yield} + \text{Capital Gains yield} = \frac{D_1} {P_0} + \frac{P_1 - P_0} {P_0} = \frac{D_1} {P_0} + g$$

**Discounted cash flow (DCF)** formula: the above formula, for if the stock is selling at its intrinsic value, then $E(r) = k$, implying that $k = \displaystyle \frac{D_1} {P_0} + g$. So we can observe the dividend yield, $\displaystyle \frac{D_1} {P_0}$, and estimate the growth rate of dividends ,$g$, and finally compute $k$.
***
However this CONSTANT-GROWTH DDM  usually applies to the regulated public utilities.

### Stock Prices and Investment Opportunities
Suppose firm ABC originally has expected earnings in the coming year of 5 dollars per share, and in principle pay out all of these earnings as dividends. If the market capitalization rate were $k = 12.5\%$, then it'll be valued at $D_1/k = \$5/.125 = \$40$ per share. Since all earnings paid out as dividends, no investment, and companies’ capital stock and earnings capacity would remain unchanged over time; earnings and dividends would not grow.

Now ABC engages in projects that generate a return on investment of $15\%$, which is greater than the required rate of return, $k = 12.5\%$.
1. plows back some earnings into its highly profitable projects, it can earn a $15\%$ rate of return for shareholders.
2. pays out all earnings as dividends and forgoes the projects. Then shareholders invest the dividends in other opportunities at a fair market rate of only $12.5\%$.

**Dividend payout ratio**: Percentage of earnings paid out as dividends.

**Plowback ratio or earnings retention ratio**: The proportion of the firm’s earnings that is reinvested in the business (and not paid out as dividends)

$$\text{New dividends} = \text{old dividends} \times \text{Dividend payout ratio}$$

And even now the dividends are less, the stock price will still goes up. Although dividends initially fall under the earnings reinvestment policy, subsequent growth in the assets of the firm because of reinvested profits will generate growth in future dividends, which will be reflected in today’s share price.

When reinvestment, the increase in the stock price reflects the fact that planned investments provide an expected rate of return greater than the required rate. $i.e.$, the investment opportunities have **positive net present value** (**positive NPV**), also called **present value of growth opportunities (PVGO)**: Net present value of a firm’s future investments.

>**e.g.**
>
>Firm ABC starts with $100$ million. The *return on investment or equity (ROE)* is $15\%$, so that total earnings are $15$ million. If there's 3 million shares totally, then the *earning per share* are $5$ dollars.
>
>Now ABC reinvest the earnings of $60\%$. Then the *value of the firm’s capital stock* is increased by $15 \times 60\% = 9$ million.
>
>Now endowed with $9\%$ more capital, the company earns $9\%$ more income and pays out $9\%$ higher dividends. The growth rate of the dividends, therefore, is
>
>$$g = \text{ROE} \times b = 0.15 \times 0.60 = 9\%$$
>
>$b$ is the **plowback ratio**
>
>Then ff the **stock price** equals its **intrinsic value**, and this growth rate can be **sustained** ($i.e.$, if the ROE and payout ratios are consistent with the long-run capabilities of the firm), then the stock should sell at
>
>$$P_0 = \frac{D_1} {k-g} = \frac{\$2} {0.125-0.09} = \$57.14$$
>
>So now, $\text{Price} = \text{No-growth value per share} + \text{PVGO}$ or $P_0 = \displaystyle \frac{E_1} {k} + \text{PVGO}$, $i.e.$, $57.14 = 40+17.14$
***
Dividend cuts are usually taken as bad news about the future prospects of the firm, and it is the new information about the firm—not the reduced dividend yield per se—that is responsible for the stock price decline.

Stock price declines in response to dividend cuts are really a response to the information conveyed by the cut.
***
But reinvestment enhances company value only if $\text{ROE} > k$.

So if say $\text{ROE} = k$, then $b=0, k=0$, and stock value per share would be $\displaystyle \frac{E_1} {k}$.

$\dagger$
$$P_0 = \frac{D_1} {k-g} = \frac{D_0 (1-b)} {k-\text{ROE}\times b} = \frac{D_0} {k}$$

$\dagger$
Another way to estimate $g$ is using the average of the industry as a benchmark.

### Life Cycles and Multistage Growth Models
**two-stage DDM**: Dividend discount model in which dividend growth is assumed to level off only at some future date.
>**e.g.** Dividend growth rate will be steady beyond 2012. Given: $\text{ROE} = 11\%$, $\text{Dividend payout ratio} = 0.30$, $\text{Risk-free rate} = 3.5\%$, $\text{Market return} = 11.5\%$, $\beta = 1.05$.
>
>$\displaystyle V_{2008} = \frac{D_{2009}} {1+k} + \frac{D_{2010}} {(1+k)^2} + \frac{D_{2011}} {(1+k)^3} + \frac{D_{2012} + V_{2012}} {(1+k)^4}$
>
>And here $k = r_f + \beta[r_M - r_f] = 11.9\%$, and since it's now with constant growth, $\displaystyle V_{2012} = \frac{D_{2013}} {k-g} = \frac{D_{2012} \;\times (1+g)} {k - g}$. Now $g$ is the only left.
>
>$g = \text{ROE} \times b = 11\% \times (1-0.3) = 7.7\%$

$\dagger$
Sometimes $b$ can be acquired by using $\displaystyle \frac{E_i - D_i} {E_i}$.

## Price-Earning Ratios
### The Price–Earnings Ratio and Growth Opportunities
**Price–earnings multiple (P/E ratio)**: The ratio of a stock’s price to its earnings per share.

And using the product of this and earnings, we can estimate the stock price.

Our first equation is

$$\frac{P_0} {E_1} = \frac{1} {k} \left[ 1 + \frac{\text{PVGO}} {E_1 / k} \right]$$

When $\text{PVGO} = 0$, it's a nongrowing perpetuity and the P/E ratio is just $\displaystyle \frac{1} {k}$.

And another one is, for a firm growing at a long-run sustainable pace,

$$P_0 = \frac{D_1} {k - (\text{ROE} \times b)} = \frac{E_1(1-b)} {k - (\text{ROE} \times b)} \Rightarrow \text{P/E Ratio} = \frac{1 - b} {k - \text{ROE} \times b}$$

$\odot$
P/E ratios commonly are taken as proxies for the expected growth in dividends or earnings.$\square$

$\dagger$
When $\text{ROE} > k$, higher $b$ makes higher $\text{P/E Ratio}$.
***
**PEG ratio**: Ratio of P/E multiple to earnings growth rate.

Commonly should be $1$. And as a rule of thumb经验法则, $\text{P/E Ratio}$ are often taken as the proxies of growth rate $g$.

>**e.g.** Given expected $\text{ROE} = 12\%$, expected earnings per share $\$2$ dollars, expected dividends of $\$1.5$, and market capitalization rate, $10\%$ per year.
>
>Plowback Ratio $b=\displaystyle \frac{\text{Earning} - \text{Dividend}} {\text{Earning}} = \frac{2-1.5} {2} = 25\%$
>
>Expected Dividend Growth Rate: $g = \text{ROE}\times b = 12\% \times 0.25 = 3\%$
>
>Expected Price based on the constant-growth DDM: $P_0 =\displaystyle \frac{D_1} {k-g} = \frac{\$1.50} {0.10 - 0.03} = \$21.43$
>
>$\text{P/E Ratio} = \displaystyle \frac{\$21.43} {\$2} = 10.71$
>
>$\text{PEG} = \displaystyle \frac{P_0/E_1} {g} = \frac{10.71} {3} = 3.57$

### P/E Ratios and Stock Risk
Riskier stocks will have lower P/E multiples. Under constant-growth model, $\displaystyle \frac{P} {E} = \frac{1-b} {k-g}$. Since riskier firms will have higher required rates of return, $k$, so the ratio get lower.

The market’s assessment that earnings in high inflation periods are of “lower quality,” artificially distorted by inflation, and warranting lower P/E ratios.

**Earnings management**: The practice of using flexibility in accounting rules to manipulate the apparent profitability of the firm.

### Combining P/E Analysis and the DDM
When calculating the intrisinc value, we can use the P/E ratio to find the last price:

$$V_{2014} = \frac{D_{2009}} {1 + k} + \frac{D_{2010}} {(1+k)^2} + \frac{D_{2011} + P_{2011}} {(1+k)^3}$$

### Other Comparative Valuation Ratios
**PRICE-TO-BOOK RATIO**: The ratio of price per share divided by book value per share.

**PRICE-TO-CASH-FLOW RATIO**: The ratio of price to cash flow per share. Cash flow, which tracks cash actually flowing into or out of the firm, is less affected by accounting decisions.

**PRICE-TO-SALES RATIO**: The ratio of stock price to the annual sales per share, since many start-up firms have no earnings.

## Free Cash Flow Valuation Approaches
**Free Cash Flow**: cash flow available to the firm or the equityholders net of capital expenditures. And it's useful for firms that pay no dividends

**Free Cash Flow for the Firm (FCFF)**:

$$\text{FCFF} = \text{EBIT}(1 - t_c) + \text{Depreciation} - \text{Capital Expenditures} - \text{Increase in NWC}$$

where, $\text{EBIT}$ is the **earnings before interest and taxes**, $t_c$ is the corporate tax rate, $\text{NWC}$ is the net working capital.

Another one is **Free Cash Flow for the Equityholders (FCFE)**:

$$\text{FCFE} = \text{FCFF} - \text{Interest expense} \times (1 - t_c) + \text{Increases in net debt}$$

**Firm Value**:

$$\text{Firm Value} = \sum_{t = 1}^T \left( \frac{\text{FCFF}} {(1 + \text{WACC})^t}\right) + \frac{P_T} {(1 + \text{ WACC })^T} $$

where $\displaystyle P_T = \frac{\text{FCFF}_{T+1}} {\text{WACC} - g}$, assuming a constant-growth model, is the estimate of **terminal value** so that it can be approximately the Firm Value we want. And $\text{WACC}$ is the weighted average cost of capital.

$\dagger$
So how to calculate the $\text{WACC}$? $\text{WACC} = \displaystyle \frac{E}{V} R_e + \frac{D}{V} R_d (1 - T_c)$, where:

$R_e$: **cost of equity**
$R_d$: **cost of debt**
$E$: **market value of the firm's equity**
$D$: **market value of the firm's debt**
$V = E + D$: **total market value of the firm’s financing (equity and debt)**
$E/V$: **percentage of financing that is equity**
$D/V$: **percentage of financing that is debt**
$T_c$: **corporate tax rate**

**Intrinsic value of equity**:

$$\text{Intrinsic value of equity} = \sum_{t = 1}^T \left( \frac{\text{FCFE}} {(1 + k_E)^t}\right) + \frac{P_T} {(1 + k_E)^T}$$

where $\displaystyle P_T = \frac{\text{FCFE}_{T+1}} {k_E - g}$, assuming a constant-growth model, is the estimate of terminal value. And $\text{WACC}$ is the weighted average cost of capital.

## Summary
- One approach to firm valuation is to focus on the firm’s book value, either as it appears on the balance sheet or adjusted to reflect the current replacement cost of assets or the liquidation value. Another approach is to focus on the present value of expected future dividends.
- The dividend discount model holds that the price of a share of stock should equal the present value of all future dividends per share, discounted at an interest rate commensurate with the risk of the stock.
- The constant-growth version of the DDM asserts that if dividends are expected to grow at a constant rate forever, then the intrinsic value of the stock is determined by the formula
$$V_0 = \frac{D_1} {k-g}$$
- This version of the DDM is simplistic in its assumption of a constant value of g. There are more sophisticated multistage versions of the model for more complex environments. When the constant-growth assumption is reasonably satisfied, however, the formula can be inverted to infer the market capitalization rate for the stock:
$$d = \frac{D_1} {P_0} + g$$
- Stock market analysts devote considerable attention to a company’s price–earnings ratio. The P/E ratio is a useful measure of the market’s assessment of the firm’s growth opportunities. Firms with no growth opportunities should have a P/E ratio that is just the reciprocal of the capitalization rate, k. As growth opportunities become a progressively more important component of the total value of the firm, the P/E ratio will increase.Page 432
- Many analysts form their estimates of a stock’s value by multiplying their forecast of next year’s EPS by a predicted P/E multiple. Some analysts mix the P/E approach with the dividend discount model. They use an earnings multiplier to forecast the terminal value of shares at a future date and add the present value of that terminal value with the present value of all interim dividend payments.
- The free cash flow approach is the one used most in corporate finance. The analyst first estimates the value of the firm as the present value of expected future free cash flows to the entire firm and then subtracts the value of all claims other than equity. Alternatively, the free cash flows to equity can be discounted at a discount rate appropriate to the risk of the stock.
- The models presented in this chapter can be used to explain or to forecast the behavior of the aggregate stock market. The key macroeconomic variables that determine the level of stock prices in the aggregate are interest rates and corporate profits.

## KEY TERMS
book value
constant-growth DDM
dividend discount model (DDM)
dividend payout ratio
earnings management
earnings retention ratio
intrinsic value
liquidation value
market capitalization rate
PEG ratio
plowback ratio
present value of growth opportunities (PVGO)
price–earnings multiple
replacement cost
Tobin’s q
two-stage DDM

# Assignment
1. The market capitalization rate on the stock of Aberdeen Wholesale Company is $11\%$. Its expected ROE is $12\%$, and its expected EPS is $8$ dollar. If the firm's plowback ratio is $65\%$, its P/E ratio will be
> $$\begin{align}
\text{Dividend payout ratio} = 1 - b &= 1 – 65\% = 35\% \\
\text{Expected dividend} = E[D_1] &= 35\% × \$8 = \$2.80 \\
\text{Growth rate} = g = \text{ROE} \times b &= 12\% \times 65\% = 7.80\% \\
\text{Value} = \frac{D_1} {k - g} &= \$2.80/(0.11 – 0.078) = \$87.50 \\
\text{P/E Ratio} = \frac{\text{Market Value}} {\text{EPS}}&= \$87.50/\$8 = 10.94
\end{align}$$
2. Weyerhaeuser Incorporated has a balance sheet that lists $\$99$ million in assets, $\$59$ million in liabilities, and $40$ million in common shareholders' equity. It has $1$ million common shares outstanding. The replacement cost of its assets is $112$ million. Its share price in the market is $53$. Its book value per share is
> $$\text{BVPS} = \frac{\text{Common shareholder's equity}} {\text{Common Outstanding Shares}} = \frac{40,000,000} {1,000,000} = 40$$
3. Sanders, Inc., paid a $5$ bucks dividend per share last year and is expected to continue to pay out $70\%$ of its earnings as dividends for the foreseeable future. If the firm is expected to generate a $14\%$ return on equity in the future, and if you require a $16\%$ return on the stock, the value of the stock is
> $$\begin{align}
g = \text{ROE} \times b &= (1 - 70\%) \times 14\% = 4.2\% \\
D_1 &= \$5 \times (1 + 4.2\%) = \$5.210 \\
\text{Intrinsic value} &= \frac{\$5.210} {16\% - 4.2\%} = \$44.15 \\
\end{align}$$
4. A firm has a stock price of $\$68.00$ per share. The firm's earnings are $\$85$ million, and the firm has $20$ million shares outstanding. The firm has an ROE of $12\%$ and a plowback of $75\%$. What is the firm's PEG ratio?
> $$\begin{align}
\text{EPS} = \frac{\text{Total Earnings}} {\text{Outstanding shares}} &= \frac{\$85,000,000} {20,000,000} = \$4.25 \\
\text{P/E Ratio} = \frac{\text{Market Value}} {\text{EPS}}&= \$68.00/\$4.25 = 16 \\
g = \text{ROE} \times b &= 12\% \times 75\% = 9.00\% \\
\text{PEG} = \frac{\text{P/E Ratio}} {100 \cdot g}&= \frac{16.00} {9.00} = 1.78
\end{align}$$
5. If a firm increases its plowback ratio, the P/E ratio would?
> The answer cannot be determined from the information given. Because only when $\text{ROE}>k$ , higher $b$ makes higher $\text{P/E Ratio}$.
6. A firm has current assets that could be sold for their book value of $\$10$ million. The book value of its fixed assets is $\$60$ million, but they could be sold for $\$95$ million today. The firm has total debt at a book value of $\$40$ million, but interest rate changes have increased the value of the debt to a current market value of $\$\$50$ million. This firm's market-to-book ratio is
>$$\begin{array}{l|c|c}
\hline
& \text{Book Values} & \text{Market Values} \\ \hline
\text{Current Assets} & \$10 & \$10 \\ \hline
\text{Fixed Assets} & \$60 & \$95 \\ \hline
\text{Total Assets} & \$70 & \$105 \\ \hline
 &  &  \\ \hline
\text{Debt} & \$40 & \$50 \\ \hline
\text{Equity, the only one not given} & \$30 & \$55 \\ \hline
\text{Total Debt \& Equity} & \$70 & \$105 \\ \hline
\end{array} \\
\text{Equity} = \text{Total Assets} - \text{Debt}\\
\frac{\text{Market Value of the Firm}} {\text{Book Value of the Firm}} = \frac{\$55} {\$30} = 1.8333
$$
7. A firm is planning on paying its first dividend of $2$ dollars three years from today. After that, dividends are expected to grow at $6\%$ per year indefinitely. The stock's required return is $14\%$. What is the intrinsic value of a share today?
> $$\begin{align}
\text{Intrinsic value after two years} = \frac{\text{Dividend after three years}} {k - g} &= \frac{\$2} {14\% - 6\%} = \$25 \\
\text{Intrinsic value today} &= \frac{\$25} {(1 + 14\%)^2}= \$19.24
\end{align}$$
8. Interior Airline is expected to pay a dividend of $\$\$3$ in the upcoming year. Dividends are expected to grow at the rate of $10\%$ per year. The risk-free rate of return is $4\%$, and the expected return on the market portfolio is $13\%$. The stock of Interior Airline has a beta of $4$. Using the constant-growth DDM, the intrinsic value of the stock is
> $$\begin{align}
g &= 10\% \\
k = r_f + \beta[E(r_M) – r_f] &= 4\% + 4(13\% − 4\%) = 40\% \\
V_0 = \frac{D_1} {k - g} = &= \frac{\$3} {40\% − 10\%} = \$10
\end{align}$$
9. A firm has a stock price of $\$54.75$ per share. The firm's earnings are $\$75$ million, and the firm has $20$ million shares outstanding. The firm has an ROE of $15\%$ and a plowback of $65\%$. What is the firm's PEG ratio?
...
10. A firm has a stock price of $\$\$55$ per share and a P/E ratio of 75. If you buy the stock at this P/E and earnings fail to grow at all, how long should you expect it to take to just recover the cost of your investment?
> $$\begin{align}
\text{EPS} = \frac{\text{Stock Price}} {\text{P/E Ratio}} &= \frac{\$54.75} {75} = \$0.73333 \text{ per year} \\
\text{Payback period} = \frac{\text{Stock Price}} {\text{EPS}}&= \frac{\$55} {\$0.73333 \text{ per year} } = 75 \text{
year}
\end{align}$$


```python
!pip install coremltools
```

    Requirement already satisfied: coremltools in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (4.1)
    Requirement already satisfied: tqdm in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (4.60.0)
    Requirement already satisfied: packaging in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (20.9)
    Requirement already satisfied: attrs in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (20.3.0)
    Requirement already satisfied: attr in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (0.3.1)
    Requirement already satisfied: numpy<1.20,>=1.14.5 in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (1.19.5)
    Requirement already satisfied: scipy in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (1.4.1)
    Requirement already satisfied: six>=1.10.0 in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (1.15.0)
    Requirement already satisfied: sympy in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (1.7.1)
    Requirement already satisfied: protobuf>=3.1.0 in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from coremltools) (3.14.0)
    Requirement already satisfied: pyparsing>=2.0.2 in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from packaging->coremltools) (2.4.7)
    Requirement already satisfied: mpmath>=0.19 in /opt/anaconda3/envs/u2net/lib/python3.7/site-packages (from sympy->coremltools) (1.2.1)

```python
# Initialise packages
from model import U2NETP
import coremltools as ct
from coremltools.proto import FeatureTypes_pb2 as ft
import torch
import torch.nn as nn
from torch.autograd import Variable
import os
import numpy as np
from PIL import Image
from torchvision import transforms
from skimage import io, transform
```

    WARNING:root:scikit-learn version 0.22.1 is not supported. Minimum required version: 0.17. Maximum required version: 0.19.2. Disabling scikit-learn conversion API.

```python
from torchvision import transforms

def save_output(pred, image):
    print(pred.shape)
    predict = pred
    predict = predict.squeeze()
    print(predict.shape)
    predict_np = predict.cpu().data.numpy()
    im = Image.fromarray(predict_np * 255).convert('RGB')
    imo = im.resize((image.size[0],image.size[1]),resample=Image.BILINEAR)

    display(imo)
```

```python
# Pre-processing

def tensor_lab(sample):
    image = sample

    tmpImg = np.zeros((image.shape[0],image.shape[1],3))
    image = image/np.max(image)

    tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229
    tmpImg[:,:,1] = (image[:,:,1]-0.456)/0.224
    tmpImg[:,:,2] = (image[:,:,2]-0.406)/0.225

        # change the r,g,b to b,r,g from [0,255] to [0,1]
    tmpImg = tmpImg.transpose((2, 0, 1))

    return torch.from_numpy(tmpImg)

def input_test_image(image_name):
    inputs_test = Image.open(image_name)
    inputs_test = inputs_test.resize((320, 320))
    inputs_test = np.asarray(inputs_test)
    inputs_test = tensor_lab(inputs_test)
    inputs_test = inputs_test.unsqueeze_(0)
    inputs_test = inputs_test.type(torch.FloatTensor)

    return inputs_test
```

```python
image_name = "test_data/test_images/0002-01.jpg"
input_image = input_test_image(image_name)
net = U2NETP(3,1)
device = torch.device('cpu')
net.load_state_dict(torch.load("saved_models/u2netp/u2netp.pth", map_location=device))
net.cpu()
net.eval()
d1,d2,d3,d4,d5,d6,d7 = net(input_image)
```

```python
save_output(d1, Image.open(image_name))
```

```python
# Initialise Baseline UNETP model.
net = U2NETP(3,1)
device = torch.device('cpu')
net.load_state_dict(torch.load("saved_models/u2netp/u2netp.pth", map_location=device))
net.cpu()
net.eval()
```

    U2NETP(
      (stage1): RSU7(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv5): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv6): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv7): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv6d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv5d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (pool12): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
      (stage2): RSU6(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv5): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv6): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv5d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (pool23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
      (stage3): RSU5(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv5): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (pool34): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
      (stage4): RSU4(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (pool45): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
      (stage5): RSU4F(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(4, 4), dilation=(4, 4))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(8, 8), dilation=(8, 8))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(4, 4), dilation=(4, 4))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (pool56): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
      (stage6): RSU4F(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(4, 4), dilation=(4, 4))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(8, 8), dilation=(8, 8))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(4, 4), dilation=(4, 4))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (stage5d): RSU4F(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(128, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(4, 4), dilation=(4, 4))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(8, 8), dilation=(8, 8))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(4, 4), dilation=(4, 4))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (stage4d): RSU4(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(128, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (stage3d): RSU5(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(128, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv5): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (stage2d): RSU6(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(128, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv5): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv6): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv5d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (stage1d): RSU7(
        (rebnconvin): REBNCONV(
          (conv_s1): Conv2d(128, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1): REBNCONV(
          (conv_s1): Conv2d(64, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv2): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv3): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv4): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv5): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (pool5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
        (rebnconv6): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv7): REBNCONV(
          (conv_s1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2), dilation=(2, 2))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv6d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv5d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv4d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv3d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv2d): REBNCONV(
          (conv_s1): Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
        (rebnconv1d): REBNCONV(
          (conv_s1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
          (bn_s1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (relu_s1): ReLU(inplace=True)
        )
      )
      (side1): Conv2d(64, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (side2): Conv2d(64, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (side3): Conv2d(64, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (side4): Conv2d(64, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (side5): Conv2d(64, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (side6): Conv2d(64, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (outconv): Conv2d(6, 1, kernel_size=(1, 1), stride=(1, 1))
    )

```python
# Trace the model.
input_image = input_test_image(image_name)
traced_model = torch.jit.trace(net, input_image)
```

```python
# Convert the model
_inputs = ct.ImageType(
    name= "input_1",
    shape= input_image.shape,
    bias=[-0.456/0.224,
          -0.406/0.225,
          -0.485/0.229],
    scale=1.0/255.0
    )
model = ct.convert(traced_model, inputs=[_inputs])
```

    WARNING:root:Tuple detected at graph output. This will be flattened in the converted model.
    Converting Frontend ==> MIL Ops: 100%|█████████▉| 2507/2509 [00:04<00:00, 569.62 ops/s]
    Running MIL optimization passes: 100%|██████████| 18/18 [00:00<00:00, 18.46 passes/s]
    Translating MIL ==> MLModel Ops: 100%|██████████| 2224/2224 [00:00<00:00, 12881.33 ops/s]

```python
# Add metadata
model.short_description = "U2-Net: Going Deeper with Nested U-Structure for Salient Object Detection"
model.license = "Apache 2.0"
model.author = "Qin, Xuebin and Zhang, Zichen and Huang, Chenyang and Dehghan, Masood and Zaiane, Osmar and Jagersand, Martin"
```

```python
# Rename inputs
spec = model.get_spec()
ct.utils.rename_feature(spec, "input_1", "in_0")
ct.utils.rename_feature(spec,"2169","out_a0")
ct.utils.rename_feature(spec,"2170","out_a1")
ct.utils.rename_feature(spec,"2171","out_a2")
ct.utils.rename_feature(spec,"2172","out_a3")
ct.utils.rename_feature(spec,"2173","out_a4")
ct.utils.rename_feature(spec,"2174","out_a5")
ct.utils.rename_feature(spec,"2175","out_a6")
model = ct.models.MLModel(spec)
model.save("creating_models/u2netp_temp.mlmodel")
```

```python
# Re-open model for modification
model = ct.models.MLModel("creating_models/u2netp_temp.mlmodel")
```

```python
# Get the model specifications
spec = model.get_spec()
```

```python
# Change model input and save
input = spec.description.input[0]
input.type.imageType.colorSpace = ft.ImageFeatureType.BGR
input.type.imageType.height = 320
input.type.imageType.width = 320

ct.utils.save_spec(spec, "creating_models/u2netp_temp_new_input.mlmodel")
```

```python
# Re-open model for modification
model = ct.models.MLModel("creating_models/u2netp_temp_new_input.mlmodel")
spec = model.get_spec()
spec_layers = getattr(spec, spec.WhichOneof("Type")).layers
output_layers = spec_layers[476:] # Get only the last output layers, may change with full-size U^2net
```

```python
# Append new layers
new_layers = []
layernum = 0;
for layer in output_layers:
    new_layer = spec_layers.add()
    new_layer.name = 'out_p' + str(layernum)
    new_layers.append('out_p' + str(layernum))

    new_layer.activation.linear.alpha = 255
    new_layer.activation.linear.beta = 0

    new_layer.input.append('out_a' + str(layernum))
    new_layer.output.append('out_p' + str(layernum))
    output_description = next(x for x in spec.description.output if x.name==output_layers[layernum].output[0])
    output_description.name = new_layer.name

    layernum = layernum + 1
```

```python
# Specify the outputs as grayscale images.
for output in spec.description.output:
    if output.name not in new_layers:
        continue
    if output.type.WhichOneof('Type') != 'multiArrayType':
        raise ValueError("%s is not a multiarray type" % output.name)

    array_shape = tuple(output.type.multiArrayType.shape)
    # print(array_shape)
    # print(output.type)

    output.type.imageType.colorSpace = ft.ImageFeatureType.ColorSpace.Value('GRAYSCALE')
    output.type.imageType.width = 320
    output.type.imageType.height = 320
```

```python
updated_model = ct.models.MLModel(spec)
model.short_description = "U2-Net: Going Deeper with Nested U-Structure for Salient Object Detection"
model.license = "Apache 2.0"
model.author = "Qin, Xuebin and Zhang, Zichen and Huang, Chenyang and Dehghan, Masood and Zaiane, Osmar and Jagersand, Martin"

updated_model.save("updated_model.mlmodel")

```

```python

```