# AxCaliber

To estimate the axon diameter distribution itself, *(Assaf et al. 2008)* proposed a method called AxCaliber.
In AxCaliber, a distribution of cylinders with different diameters are fitted to the diffusion signal. In particular, a Gamma distribution is used. A requirement of this technique is that the signal is measured perpendicular to the axon bundle direction for different gradient strengths and diffusion times.
The signal representation in AxCaliber is given as

\begin{equation}
E_{\textrm{AxCaliber}}= \underbrace{(1-f_r)\overbrace{E_h(\lambda_{\textrm{h}})}^{\textrm{Ball}}}_{\textrm{Extra-Axonal}} + \underbrace{f_r \overbrace{\Gamma(\alpha,\beta)}^{\textrm{Gamma Distribution}}*_{\mathbb{R}}\overbrace{E_r(\cdot|D_\perp)}^{\textrm{Cylinder}}}_{\textrm{Intra-Axonal}}
\end{equation}

where the cylinder was initially represented using the Callaghan model, but was later replaced with the more general Van Gelderen model *(Assaf et al. 2008, Huang et al. 2015, De Santis et al. 2016)*.

Advantages:
- Estimates the axon diameter distribution.

Limitations:
- Tissue orientation must be known for the signal to be measured perpendicular,
- Does not take axon dispersion into account,
- Does not include the effects of extra axonal restriction *(Burcaw et al. 2015)*.

## AxCaliber model with Gaussian Phase Approximation

The process of setting up the AxCaliber model with Gamma-distributed cylinder diameters is the same as setting up an axon dispersed model. We import the needed Ball and Cylinder models, and then distribute the cylinder using the DD1GammaDistributed function from distribute_models.

```python
from dmipy.distributions import distribute_models
from dmipy.signal_models import gaussian_models, cylinder_models

ball = gaussian_models.G1Ball()
cylinder = cylinder_models.C4CylinderGaussianPhaseApproximation()
gamma_cylinder = distribute_models.DD1GammaDistributed(models=[cylinder])
```

Then put the models together in a MultiCompartmentModel and display the parameters

```python
from dmipy.core import modeling_framework
axcaliber_gamma = modeling_framework.MultiCompartmentModel(models=[ball, gamma_cylinder])
axcaliber_gamma.parameter_cardinality
```

    OrderedDict([('DD1GammaDistributed_1_DD1Gamma_1_alpha', 1),
                 ('G1Ball_1_lambda_iso', 1),
                 ('DD1GammaDistributed_1_C4CylinderGaussianPhaseApproximation_1_mu',
                  2),
                 ('DD1GammaDistributed_1_DD1Gamma_1_beta', 1),
                 ('DD1GammaDistributed_1_C4CylinderGaussianPhaseApproximation_1_lambda_par',
                  1),
                 ('partial_volume_0', 1),
                 ('partial_volume_1', 1)])

Visualize the model:

```python
from IPython.display import Image
axcaliber_gamma.visualize_model_setup(view=False, cleanup=False, with_parameters=True)
Image('Model Setup.png')
```

The data we will fit is measured only along 2 gradient orientations that are perpendicular to the axon axis (along x and y axis). This means there is no data that provides information to fit parallel diffusivity "lambda_par" or the axon orientation "mu". To not fit these superfluous parameters we fix mu along the z-axis and give lambda_par an arbitrary value (it will not affect the results).

```python
axcaliber_gamma.set_fixed_parameter(
    'DD1GammaDistributed_1_C4CylinderGaussianPhaseApproximation_1_lambda_par', 1.7e-9)
axcaliber_gamma.set_fixed_parameter(
    'DD1GammaDistributed_1_C4CylinderGaussianPhaseApproximation_1_mu', [0, 0])
```

## Load AxCaliber-compatible data

For the example data, we kindly make use of a cat spinal cord dataset hosted at the White Matter Microscopy Database (https://osf.io/yp4qg/). The data includes 2D Axcaliber data, 3D multi-shell data and the corresponding histology values for axon diameter, intra-axonal volume fraction (and others).

```python
from dmipy.data import saved_data
scheme_spinal_cord, data_spinal_cord = saved_data.duval_cat_spinal_cord_2d()
```

    This data was used by Duval et al. 'Validation of quantitative MRI metrics using full slice histology with automatic axon segmentation', ISMRM 2016. Reference at Cohen-Adad et al. White Matter Microscopy Database. http://doi.org/10.17605/OSF.IO/YP4QG

```python
import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(data_spinal_cord.signal[:,:,0,0])
plt.title('b0 of spinal cord data')
plt.axis('off');
```

Printing the acquisition scheme information we can see the Delta-shells of the acquisition.

```python
scheme_spinal_cord.print_acquisition_info
```

    Acquisition scheme summary

    total number of measurements: 1791
    number of b0 measurements: 72
    number of DWI shells: 418

    shell_index |# of DWIs |bvalue [s/mm^2] |gradient strength [mT/m] |delta [ms] |Delta[ms] |TE[ms]
    0           |96        |191             |0                        |3.0        |7.0       |36.152
    1           |4         |627             |402                      |3.0        |7.0       |36.152
    2           |4         |681             |419                      |3.0        |7.0       |36.152
    3           |4         |738             |437                      |3.0        |7.0       |36.152
    4           |4         |797             |454                      |3.0        |7.0       |36.152
    5           |4         |858             |471                      |3.0        |7.0       |36.152
    6           |4         |922             |488                      |3.0        |7.0       |36.152
    7           |4         |988             |505                      |3.0        |7.0       |36.152
    8           |4         |1056            |522                      |3.0        |7.0       |36.152
    9           |4         |1126            |539                      |3.0        |7.0       |36.152
    10          |4         |1199            |557                      |3.0        |7.0       |36.152
    11          |4         |1274            |574                      |3.0        |7.0       |36.152
    12          |4         |1351            |591                      |3.0        |7.0       |36.152
    13          |4         |1431            |608                      |3.0        |7.0       |36.152
    14          |4         |1512            |625                      |3.0        |7.0       |36.152
    15          |4         |1596            |642                      |3.0        |7.0       |36.152
    16          |4         |1683            |659                      |3.0        |7.0       |36.152
    17          |4         |1771            |677                      |3.0        |7.0       |36.152
    18          |4         |1862            |694                      |3.0        |7.0       |36.152
    19          |4         |1955            |711                      |3.0        |7.0       |36.152
    20          |4         |2051            |728                      |3.0        |7.0       |36.152
    21          |4         |2148            |745                      |3.0        |7.0       |36.152
    22          |4         |2248            |762                      |3.0        |7.0       |36.152
    23          |3         |2350            |779                      |3.0        |7.0       |36.152
    24          |3         |2455            |797                      |3.0        |7.0       |36.152
    25          |3         |2562            |814                      |3.0        |7.0       |36.152
    26          |3         |2671            |831                      |3.0        |7.0       |36.152
    27          |3         |2782            |848                      |3.0        |7.0       |36.152
    28          |20        |31              |0                        |3.0        |40.0      |57.288
    29          |4         |149             |77                       |3.0        |40.0      |57.288
    30          |4         |223             |94                       |3.0        |40.0      |57.288
    31          |4         |311             |111                      |3.0        |40.0      |57.288
    32          |4         |415             |128                      |3.0        |40.0      |57.288
    33          |4         |533             |145                      |3.0        |40.0      |57.288
    34          |4         |666             |162                      |3.0        |40.0      |57.288
    35          |4         |813             |179                      |3.0        |40.0      |57.288
    36          |4         |976             |197                      |3.0        |40.0      |57.288
    37          |4         |1153            |214                      |3.0        |40.0      |57.288
    38          |4         |1345            |231                      |3.0        |40.0      |57.288
    39          |4         |1551            |248                      |3.0        |40.0      |57.288
    40          |4         |1773            |265                      |3.0        |40.0      |57.288
    41          |4         |2009            |282                      |3.0        |40.0      |57.288
    42          |4         |2260            |299                      |3.0        |40.0      |57.288
    43          |4         |2526            |317                      |3.0        |40.0      |57.288
    44          |4         |2806            |334                      |3.0        |40.0      |57.288
    45          |4         |3101            |351                      |3.0        |40.0      |57.288
    46          |4         |3411            |368                      |3.0        |40.0      |57.288
    47          |4         |3736            |385                      |3.0        |40.0      |57.288
    48          |4         |4076            |402                      |3.0        |40.0      |57.288
    49          |4         |4430            |419                      |3.0        |40.0      |57.288
    50          |4         |4799            |437                      |3.0        |40.0      |57.288
    51          |4         |5183            |454                      |3.0        |40.0      |57.288
    52          |4         |5582            |471                      |3.0        |40.0      |57.288
    53          |4         |5995            |488                      |3.0        |40.0      |57.288
    54          |4         |6423            |505                      |3.0        |40.0      |57.288
    55          |4         |6866            |522                      |3.0        |40.0      |57.288
    56          |4         |7323            |539                      |3.0        |40.0      |57.288
    57          |4         |7796            |557                      |3.0        |40.0      |57.288
    58          |4         |8283            |574                      |3.0        |40.0      |57.288
    59          |4         |8785            |591                      |3.0        |40.0      |57.288
    60          |4         |9301            |608                      |3.0        |40.0      |57.288
    61          |4         |9833            |625                      |3.0        |40.0      |57.288
    62          |4         |10379           |642                      |3.0        |40.0      |57.288
    63          |4         |10940           |659                      |3.0        |40.0      |57.288
    64          |4         |11516           |677                      |3.0        |40.0      |57.288
    65          |4         |12106           |694                      |3.0        |40.0      |57.288
    66          |4         |12711           |711                      |3.0        |40.0      |57.288
    67          |4         |13332           |728                      |3.0        |40.0      |57.288
    68          |4         |13966           |745                      |3.0        |40.0      |57.288
    69          |4         |14616           |762                      |3.0        |40.0      |57.288
    70          |3         |15280           |779                      |3.0        |40.0      |57.288
    71          |3         |15959           |797                      |3.0        |40.0      |57.288
    72          |3         |16653           |814                      |3.0        |40.0      |57.288
    73          |3         |17362           |831                      |3.0        |40.0      |57.288
    74          |3         |18085           |848                      |3.0        |40.0      |57.288
    75          |12        |10              |0                        |8.0        |12.0      |46.152
    76          |4         |78              |42                       |8.0        |12.0      |46.152
    77          |4         |153             |59                       |8.0        |12.0      |46.152
    78          |4         |254             |77                       |8.0        |12.0      |46.152
    79          |4         |379             |94                       |8.0        |12.0      |46.152
    80          |4         |530             |111                      |8.0        |12.0      |46.152
    81          |4         |706             |128                      |8.0        |12.0      |46.152
    82          |4         |907             |145                      |8.0        |12.0      |46.152
    83          |4         |1133            |162                      |8.0        |12.0      |46.152
    84          |4         |1384            |179                      |8.0        |12.0      |46.152
    85          |4         |1661            |197                      |8.0        |12.0      |46.152
    86          |4         |1962            |214                      |8.0        |12.0      |46.152
    87          |4         |2289            |231                      |8.0        |12.0      |46.152
    88          |4         |2641            |248                      |8.0        |12.0      |46.152
    89          |4         |3017            |265                      |8.0        |12.0      |46.152
    90          |4         |3419            |282                      |8.0        |12.0      |46.152
    91          |4         |3846            |299                      |8.0        |12.0      |46.152
    92          |4         |4299            |317                      |8.0        |12.0      |46.152
    93          |4         |4776            |334                      |8.0        |12.0      |46.152
    94          |4         |5278            |351                      |8.0        |12.0      |46.152
    95          |4         |5806            |368                      |8.0        |12.0      |46.152
    96          |4         |6359            |385                      |8.0        |12.0      |46.152
    97          |4         |6937            |402                      |8.0        |12.0      |46.152
    98          |4         |7539            |419                      |8.0        |12.0      |46.152
    99          |4         |8167            |437                      |8.0        |12.0      |46.152
    100         |4         |8820            |454                      |8.0        |12.0      |46.152
    101         |4         |9499            |471                      |8.0        |12.0      |46.152
    102         |4         |10202           |488                      |8.0        |12.0      |46.152
    103         |4         |10931           |505                      |8.0        |12.0      |46.152
    104         |4         |11684           |522                      |8.0        |12.0      |46.152
    105         |4         |12463           |539                      |8.0        |12.0      |46.152
    106         |4         |13267           |557                      |8.0        |12.0      |46.152
    107         |4         |14096           |574                      |8.0        |12.0      |46.152
    108         |4         |14950           |591                      |8.0        |12.0      |46.152
    109         |4         |15830           |608                      |8.0        |12.0      |46.152
    110         |4         |16734           |625                      |8.0        |12.0      |46.152
    111         |4         |17664           |642                      |8.0        |12.0      |46.152
    112         |4         |18618           |659                      |8.0        |12.0      |46.152
    113         |4         |19598           |677                      |8.0        |12.0      |46.152
    114         |4         |20603           |694                      |8.0        |12.0      |46.152
    115         |4         |21633           |711                      |8.0        |12.0      |46.152
    116         |4         |22688           |728                      |8.0        |12.0      |46.152
    117         |4         |23769           |745                      |8.0        |12.0      |46.152
    118         |4         |24874           |762                      |8.0        |12.0      |46.152
    119         |3         |26004           |779                      |8.0        |12.0      |46.152
    120         |3         |27160           |797                      |8.0        |12.0      |46.152
    121         |3         |28341           |814                      |8.0        |12.0      |46.152
    122         |3         |29547           |831                      |8.0        |12.0      |46.152
    123         |3         |30778           |848                      |8.0        |12.0      |46.152
    124         |12        |13              |0                        |8.0        |15.0      |46.152
    125         |4         |103             |42                       |8.0        |15.0      |46.152
    126         |4         |203             |59                       |8.0        |15.0      |46.152
    127         |4         |336             |77                       |8.0        |15.0      |46.152
    128         |4         |502             |94                       |8.0        |15.0      |46.152
    129         |4         |701             |111                      |8.0        |15.0      |46.152
    130         |4         |933             |128                      |8.0        |15.0      |46.152
    131         |4         |1199            |145                      |8.0        |15.0      |46.152
    132         |4         |1498            |162                      |8.0        |15.0      |46.152
    133         |4         |1829            |179                      |8.0        |15.0      |46.152
    134         |4         |2195            |197                      |8.0        |15.0      |46.152
    135         |4         |2593            |214                      |8.0        |15.0      |46.152
    136         |4         |3025            |231                      |8.0        |15.0      |46.152
    137         |4         |3489            |248                      |8.0        |15.0      |46.152
    138         |4         |3987            |265                      |8.0        |15.0      |46.152
    139         |4         |4518            |282                      |8.0        |15.0      |46.152
    140         |4         |5083            |299                      |8.0        |15.0      |46.152
    141         |4         |5681            |317                      |8.0        |15.0      |46.152
    142         |4         |6311            |334                      |8.0        |15.0      |46.152
    143         |4         |6975            |351                      |8.0        |15.0      |46.152
    144         |4         |7672            |368                      |8.0        |15.0      |46.152
    145         |4         |8403            |385                      |8.0        |15.0      |46.152
    146         |4         |9166            |402                      |8.0        |15.0      |46.152
    147         |4         |9963            |419                      |8.0        |15.0      |46.152
    148         |4         |10793           |437                      |8.0        |15.0      |46.152
    149         |4         |11656           |454                      |8.0        |15.0      |46.152
    150         |4         |12553           |471                      |8.0        |15.0      |46.152
    151         |4         |13482           |488                      |8.0        |15.0      |46.152
    152         |4         |14445           |505                      |8.0        |15.0      |46.152
    153         |4         |15440           |522                      |8.0        |15.0      |46.152
    154         |4         |16469           |539                      |8.0        |15.0      |46.152
    155         |4         |17532           |557                      |8.0        |15.0      |46.152
    156         |4         |18628           |574                      |8.0        |15.0      |46.152
    157         |4         |19756           |591                      |8.0        |15.0      |46.152
    158         |4         |20918           |608                      |8.0        |15.0      |46.152
    159         |4         |22113           |625                      |8.0        |15.0      |46.152
    160         |4         |23342           |642                      |8.0        |15.0      |46.152
    161         |4         |24603           |659                      |8.0        |15.0      |46.152
    162         |4         |25898           |677                      |8.0        |15.0      |46.152
    163         |4         |27225           |694                      |8.0        |15.0      |46.152
    164         |4         |28586           |711                      |8.0        |15.0      |46.152
    165         |4         |29981           |728                      |8.0        |15.0      |46.152
    166         |4         |31409           |745                      |8.0        |15.0      |46.152
    167         |4         |32869           |762                      |8.0        |15.0      |46.152
    168         |3         |34363           |779                      |8.0        |15.0      |46.152
    169         |3         |35890           |797                      |8.0        |15.0      |46.152
    170         |3         |37451           |814                      |8.0        |15.0      |46.152
    171         |3         |39044           |831                      |8.0        |15.0      |46.152
    172         |3         |40670           |848                      |8.0        |15.0      |46.152
    173         |12        |19              |0                        |8.0        |20.0      |46.152
    174         |4         |145             |42                       |8.0        |20.0      |46.152
    175         |4         |285             |59                       |8.0        |20.0      |46.152
    176         |4         |472             |77                       |8.0        |20.0      |46.152
    177         |4         |705             |94                       |8.0        |20.0      |46.152
    178         |4         |985             |111                      |8.0        |20.0      |46.152
    179         |4         |1312            |128                      |8.0        |20.0      |46.152
    180         |4         |1685            |145                      |8.0        |20.0      |46.152
    181         |4         |2105            |162                      |8.0        |20.0      |46.152
    182         |4         |2571            |179                      |8.0        |20.0      |46.152
    183         |4         |3085            |197                      |8.0        |20.0      |46.152
    184         |4         |3645            |214                      |8.0        |20.0      |46.152
    185         |4         |4251            |231                      |8.0        |20.0      |46.152
    186         |4         |4904            |248                      |8.0        |20.0      |46.152
    187         |4         |5604            |265                      |8.0        |20.0      |46.152
    188         |4         |6350            |282                      |8.0        |20.0      |46.152
    189         |4         |7144            |299                      |8.0        |20.0      |46.152
    190         |4         |7984            |317                      |8.0        |20.0      |46.152
    191         |4         |8870            |334                      |8.0        |20.0      |46.152
    192         |4         |9803            |351                      |8.0        |20.0      |46.152
    193         |4         |10783           |368                      |8.0        |20.0      |46.152
    194         |4         |11810           |385                      |8.0        |20.0      |46.152
    195         |4         |12883           |402                      |8.0        |20.0      |46.152
    196         |4         |14002           |419                      |8.0        |20.0      |46.152
    197         |4         |15168           |437                      |8.0        |20.0      |46.152
    198         |4         |16381           |454                      |8.0        |20.0      |46.152
    199         |4         |17642           |471                      |8.0        |20.0      |46.152
    200         |4         |18948           |488                      |8.0        |20.0      |46.152
    201         |4         |20301           |505                      |8.0        |20.0      |46.152
    202         |4         |21700           |522                      |8.0        |20.0      |46.152
    203         |4         |23146           |539                      |8.0        |20.0      |46.152
    204         |4         |24640           |557                      |8.0        |20.0      |46.152
    205         |4         |26179           |574                      |8.0        |20.0      |46.152
    206         |4         |27766           |591                      |8.0        |20.0      |46.152
    207         |4         |29398           |608                      |8.0        |20.0      |46.152
    208         |4         |31078           |625                      |8.0        |20.0      |46.152
    209         |4         |32805           |642                      |8.0        |20.0      |46.152
    210         |4         |34578           |659                      |8.0        |20.0      |46.152
    211         |4         |36397           |677                      |8.0        |20.0      |46.152
    212         |4         |38263           |694                      |8.0        |20.0      |46.152
    213         |4         |40176           |711                      |8.0        |20.0      |46.152
    214         |4         |42136           |728                      |8.0        |20.0      |46.152
    215         |4         |44142           |745                      |8.0        |20.0      |46.152
    216         |4         |46195           |762                      |8.0        |20.0      |46.152
    217         |3         |48294           |779                      |8.0        |20.0      |46.152
    218         |3         |50440           |797                      |8.0        |20.0      |46.152
    219         |3         |52634           |814                      |8.0        |20.0      |46.152
    220         |3         |54873           |831                      |8.0        |20.0      |46.152
    221         |3         |57159           |848                      |8.0        |20.0      |46.152
    222         |8         |3               |0                        |8.0        |25.0      |47.288
    223         |4         |67              |25                       |8.0        |25.0      |47.288
    224         |4         |187             |42                       |8.0        |25.0      |47.288
    225         |4         |368             |59                       |8.0        |25.0      |47.288
    226         |4         |608             |77                       |8.0        |25.0      |47.288
    227         |4         |909             |94                       |8.0        |25.0      |47.288
    228         |4         |1269            |111                      |8.0        |25.0      |47.288
    229         |4         |1690            |128                      |8.0        |25.0      |47.288
    230         |4         |2171            |145                      |8.0        |25.0      |47.288
    231         |4         |2712            |162                      |8.0        |25.0      |47.288
    232         |4         |3313            |179                      |8.0        |25.0      |47.288
    233         |4         |3974            |197                      |8.0        |25.0      |47.288
    234         |4         |4696            |214                      |8.0        |25.0      |47.288
    235         |4         |5478            |231                      |8.0        |25.0      |47.288
    236         |4         |6319            |248                      |8.0        |25.0      |47.288
    237         |4         |7221            |265                      |8.0        |25.0      |47.288
    238         |4         |8182            |282                      |8.0        |25.0      |47.288
    239         |4         |9205            |299                      |8.0        |25.0      |47.288
    240         |4         |10287           |317                      |8.0        |25.0      |47.288
    241         |4         |11429           |334                      |8.0        |25.0      |47.288
    242         |4         |12631           |351                      |8.0        |25.0      |47.288
    243         |4         |13893           |368                      |8.0        |25.0      |47.288
    244         |4         |15216           |385                      |8.0        |25.0      |47.288
    245         |4         |16599           |402                      |8.0        |25.0      |47.288
    246         |4         |18041           |419                      |8.0        |25.0      |47.288
    247         |4         |19544           |437                      |8.0        |25.0      |47.288
    248         |4         |21107           |454                      |8.0        |25.0      |47.288
    249         |4         |22731           |471                      |8.0        |25.0      |47.288
    250         |4         |24414           |488                      |8.0        |25.0      |47.288
    251         |4         |26157           |505                      |8.0        |25.0      |47.288
    252         |4         |27960           |522                      |8.0        |25.0      |47.288
    253         |4         |29823           |539                      |8.0        |25.0      |47.288
    254         |4         |31748           |557                      |8.0        |25.0      |47.288
    255         |4         |33731           |574                      |8.0        |25.0      |47.288
    256         |4         |35775           |591                      |8.0        |25.0      |47.288
    257         |4         |37879           |608                      |8.0        |25.0      |47.288
    258         |4         |40043           |625                      |8.0        |25.0      |47.288
    259         |4         |42268           |642                      |8.0        |25.0      |47.288
    260         |4         |44552           |659                      |8.0        |25.0      |47.288
    261         |4         |46896           |677                      |8.0        |25.0      |47.288
    262         |4         |49300           |694                      |8.0        |25.0      |47.288
    263         |4         |51765           |711                      |8.0        |25.0      |47.288
    264         |4         |54291           |728                      |8.0        |25.0      |47.288
    265         |4         |56875           |745                      |8.0        |25.0      |47.288
    266         |4         |59520           |762                      |8.0        |25.0      |47.288
    267         |3         |62225           |779                      |8.0        |25.0      |47.288
    268         |3         |64990           |797                      |8.0        |25.0      |47.288
    269         |3         |67817           |814                      |8.0        |25.0      |47.288
    270         |3         |70702           |831                      |8.0        |25.0      |47.288
    271         |3         |73647           |848                      |8.0        |25.0      |47.288
    272         |8         |4               |0                        |8.0        |30.0      |52.288
    273         |4         |82              |25                       |8.0        |30.0      |52.288
    274         |4         |229             |42                       |8.0        |30.0      |52.288
    275         |4         |450             |59                       |8.0        |30.0      |52.288
    276         |4         |744             |77                       |8.0        |30.0      |52.288
    277         |4         |1112            |94                       |8.0        |30.0      |52.288
    278         |4         |1554            |111                      |8.0        |30.0      |52.288
    279         |4         |2069            |128                      |8.0        |30.0      |52.288
    280         |4         |2657            |145                      |8.0        |30.0      |52.288
    281         |4         |3319            |162                      |8.0        |30.0      |52.288
    282         |4         |4055            |179                      |8.0        |30.0      |52.288
    283         |4         |4864            |197                      |8.0        |30.0      |52.288
    284         |4         |5748            |214                      |8.0        |30.0      |52.288
    285         |4         |6704            |231                      |8.0        |30.0      |52.288
    286         |4         |7734            |248                      |8.0        |30.0      |52.288
    287         |4         |8837            |265                      |8.0        |30.0      |52.288
    288         |4         |10014           |282                      |8.0        |30.0      |52.288
    289         |4         |11266           |299                      |8.0        |30.0      |52.288
    290         |4         |12590           |317                      |8.0        |30.0      |52.288
    291         |4         |13988           |334                      |8.0        |30.0      |52.288
    292         |4         |15459           |351                      |8.0        |30.0      |52.288
    293         |4         |17004           |368                      |8.0        |30.0      |52.288
    294         |4         |18623           |385                      |8.0        |30.0      |52.288
    295         |4         |20315           |402                      |8.0        |30.0      |52.288
    296         |4         |22081           |419                      |8.0        |30.0      |52.288
    297         |4         |23920           |437                      |8.0        |30.0      |52.288
    298         |4         |25832           |454                      |8.0        |30.0      |52.288
    299         |4         |27820           |471                      |8.0        |30.0      |52.288
    300         |4         |29879           |488                      |8.0        |30.0      |52.288
    301         |4         |32013           |505                      |8.0        |30.0      |52.288
    302         |4         |34220           |522                      |8.0        |30.0      |52.288
    303         |4         |36500           |539                      |8.0        |30.0      |52.288
    304         |4         |38856           |557                      |8.0        |30.0      |52.288
    305         |4         |41283           |574                      |8.0        |30.0      |52.288
    306         |4         |43784           |591                      |8.0        |30.0      |52.288
    307         |4         |46359           |608                      |8.0        |30.0      |52.288
    308         |4         |49007           |625                      |8.0        |30.0      |52.288
    309         |4         |51731           |642                      |8.0        |30.0      |52.288
    310         |4         |54526           |659                      |8.0        |30.0      |52.288
    311         |4         |57395           |677                      |8.0        |30.0      |52.288
    312         |4         |60338           |694                      |8.0        |30.0      |52.288
    313         |4         |63354           |711                      |8.0        |30.0      |52.288
    314         |4         |66446           |728                      |8.0        |30.0      |52.288
    315         |4         |69609           |745                      |8.0        |30.0      |52.288
    316         |4         |72846           |762                      |8.0        |30.0      |52.288
    317         |3         |76156           |779                      |8.0        |30.0      |52.288
    318         |3         |79540           |797                      |8.0        |30.0      |52.288
    319         |3         |82999           |814                      |8.0        |30.0      |52.288
    320         |3         |86531           |831                      |8.0        |30.0      |52.288
    321         |3         |90135           |848                      |8.0        |30.0      |52.288
    322         |8         |5               |0                        |8.0        |35.0      |57.288
    323         |4         |97              |25                       |8.0        |35.0      |57.288
    324         |4         |271             |42                       |8.0        |35.0      |57.288
    325         |4         |533             |59                       |8.0        |35.0      |57.288
    326         |4         |881             |77                       |8.0        |35.0      |57.288
    327         |4         |1316            |94                       |8.0        |35.0      |57.288
    328         |4         |1838            |111                      |8.0        |35.0      |57.288
    329         |4         |2447            |128                      |8.0        |35.0      |57.288
    330         |4         |3144            |145                      |8.0        |35.0      |57.288
    331         |4         |3927            |162                      |8.0        |35.0      |57.288
    332         |4         |4797            |179                      |8.0        |35.0      |57.288
    333         |4         |5754            |197                      |8.0        |35.0      |57.288
    334         |4         |6799            |214                      |8.0        |35.0      |57.288
    335         |4         |7930            |231                      |8.0        |35.0      |57.288
    336         |4         |9149            |248                      |8.0        |35.0      |57.288
    337         |4         |10454           |265                      |8.0        |35.0      |57.288
    338         |4         |11846           |282                      |8.0        |35.0      |57.288
    339         |4         |13327           |299                      |8.0        |35.0      |57.288
    340         |4         |14893           |317                      |8.0        |35.0      |57.288
    341         |4         |16546           |334                      |8.0        |35.0      |57.288
    342         |4         |18287           |351                      |8.0        |35.0      |57.288
    343         |4         |20114           |368                      |8.0        |35.0      |57.288
    344         |4         |22030           |385                      |8.0        |35.0      |57.288
    345         |4         |24031           |402                      |8.0        |35.0      |57.288
    346         |4         |26120           |419                      |8.0        |35.0      |57.288
    347         |4         |28295           |437                      |8.0        |35.0      |57.288
    348         |4         |30558           |454                      |8.0        |35.0      |57.288
    349         |4         |32909           |471                      |8.0        |35.0      |57.288
    350         |4         |35345           |488                      |8.0        |35.0      |57.288
    351         |4         |37869           |505                      |8.0        |35.0      |57.288
    352         |4         |40480           |522                      |8.0        |35.0      |57.288
    353         |4         |43177           |539                      |8.0        |35.0      |57.288
    354         |4         |45963           |557                      |8.0        |35.0      |57.288
    355         |4         |48835           |574                      |8.0        |35.0      |57.288
    356         |4         |51794           |591                      |8.0        |35.0      |57.288
    357         |4         |54840           |608                      |8.0        |35.0      |57.288
    358         |4         |57972           |625                      |8.0        |35.0      |57.288
    359         |4         |61194           |642                      |8.0        |35.0      |57.288
    360         |4         |64501           |659                      |8.0        |35.0      |57.288
    361         |4         |67895           |677                      |8.0        |35.0      |57.288
    362         |4         |71375           |694                      |8.0        |35.0      |57.288
    363         |4         |74943           |711                      |8.0        |35.0      |57.288
    364         |4         |78600           |728                      |8.0        |35.0      |57.288
    365         |4         |82342           |745                      |8.0        |35.0      |57.288
    366         |4         |86171           |762                      |8.0        |35.0      |57.288
    367         |3         |90087           |779                      |8.0        |35.0      |57.288
    368         |3         |94090           |797                      |8.0        |35.0      |57.288
    369         |3         |98182           |814                      |8.0        |35.0      |57.288
    370         |3         |102359          |831                      |8.0        |35.0      |57.288
    371         |3         |106623          |848                      |8.0        |35.0      |57.288
    372         |8         |6               |0                        |8.0        |40.0      |62.288
    373         |4         |113             |25                       |8.0        |40.0      |62.288
    374         |4         |314             |42                       |8.0        |40.0      |62.288
    375         |4         |615             |59                       |8.0        |40.0      |62.288
    376         |4         |1017            |77                       |8.0        |40.0      |62.288
    377         |4         |1519            |94                       |8.0        |40.0      |62.288
    378         |4         |2122            |111                      |8.0        |40.0      |62.288
    379         |4         |2826            |128                      |8.0        |40.0      |62.288
    380         |4         |3630            |145                      |8.0        |40.0      |62.288
    381         |4         |4534            |162                      |8.0        |40.0      |62.288
    382         |4         |5539            |179                      |8.0        |40.0      |62.288
    383         |4         |6644            |197                      |8.0        |40.0      |62.288
    384         |4         |7851            |214                      |8.0        |40.0      |62.288
    385         |4         |9157            |231                      |8.0        |40.0      |62.288
    386         |4         |10564           |248                      |8.0        |40.0      |62.288
    387         |4         |12071           |265                      |8.0        |40.0      |62.288
    388         |4         |13678           |282                      |8.0        |40.0      |62.288
    389         |4         |15387           |299                      |8.0        |40.0      |62.288
    390         |4         |17196           |317                      |8.0        |40.0      |62.288
    391         |4         |19105           |334                      |8.0        |40.0      |62.288
    392         |4         |21115           |351                      |8.0        |40.0      |62.288
    393         |4         |23225           |368                      |8.0        |40.0      |62.288
    394         |4         |25436           |385                      |8.0        |40.0      |62.288
    395         |4         |27748           |402                      |8.0        |40.0      |62.288
    396         |4         |30159           |419                      |8.0        |40.0      |62.288
    397         |4         |32671           |437                      |8.0        |40.0      |62.288
    398         |4         |35283           |454                      |8.0        |40.0      |62.288
    399         |4         |37998           |471                      |8.0        |40.0      |62.288
    400         |4         |40811           |488                      |8.0        |40.0      |62.288
    401         |4         |43725           |505                      |8.0        |40.0      |62.288
    402         |4         |46739           |522                      |8.0        |40.0      |62.288
    403         |4         |49854           |539                      |8.0        |40.0      |62.288
    404         |4         |53071           |557                      |8.0        |40.0      |62.288
    405         |4         |56387           |574                      |8.0        |40.0      |62.288
    406         |4         |59803           |591                      |8.0        |40.0      |62.288
    407         |4         |63320           |608                      |8.0        |40.0      |62.288
    408         |4         |66937           |625                      |8.0        |40.0      |62.288
    409         |4         |70657           |642                      |8.0        |40.0      |62.288
    410         |4         |74475           |659                      |8.0        |40.0      |62.288
    411         |4         |78394           |677                      |8.0        |40.0      |62.288
    412         |4         |82413           |694                      |8.0        |40.0      |62.288
    413         |4         |86533           |711                      |8.0        |40.0      |62.288
    414         |4         |90755           |728                      |8.0        |40.0      |62.288
    415         |4         |95076           |745                      |8.0        |40.0      |62.288
    416         |4         |99497           |762                      |8.0        |40.0      |62.288
    417         |3         |104018          |779                      |8.0        |40.0      |62.288
    418         |3         |108640          |797                      |8.0        |40.0      |62.288
    419         |3         |113365          |814                      |8.0        |40.0      |62.288
    420         |3         |118188          |831                      |8.0        |40.0      |62.288
    421         |3         |123112          |848                      |8.0        |40.0      |62.288

The 2D data only has data measured in the xy-plane, where we only use the [1, 0, 0] dummy direction for b0 measurements. We can see the unique gradient directions as follows:

```python
import numpy as np
unique_directions = np.unique(scheme_spinal_cord.gradient_directions, axis=0)
unique_directions
```

    array([[-0.70711 , -0.70711 ,  0.      ],
           [-0.70711 ,  0.70711 ,  0.      ],
           [-0.707107, -0.707107,  0.      ],
           [-0.707107,  0.707107,  0.      ],
           [ 0.707107, -0.707107,  0.      ],
           [ 0.707107,  0.707107,  0.      ],
           [ 0.70711 , -0.70711 ,  0.      ],
           [ 0.70711 ,  0.70711 ,  0.      ],
           [ 1.      ,  0.      ,  0.      ]])

It is valuable to check if actually the signal between the two orthogonal directions is the same:

```python
dir1mask = np.all(scheme_spinal_cord.gradient_directions == unique_directions[0], axis=1)
dir2mask = np.all(scheme_spinal_cord.gradient_directions == unique_directions[1], axis=1)

test_voxel = data_spinal_cord.signal[20, 20, 0]
data_dir1 = test_voxel[dir1mask]
data_dir2 = test_voxel[dir2mask]

Delta_dir1 = scheme_spinal_cord.Delta[dir1mask]
Delta_dir2 = scheme_spinal_cord.Delta[dir2mask]

G = scheme_spinal_cord.gradient_strengths
colors = ['r', 'g', 'b', 'orange']

unique_Deltas = np.unique(scheme_spinal_cord.shell_Delta)[2:-1:2]
for i, Delta_ in enumerate(unique_Deltas):
    mask_Delta1 = Delta_dir1 == Delta_
    mask_Delta2 = Delta_dir2 == Delta_

    plt.plot(G[dir1mask][mask_Delta1], data_dir1[mask_Delta1], c=colors[i], label='dir1 Delta='+str(Delta_))
    plt.plot(G[dir2mask][mask_Delta2], data_dir2[mask_Delta2], c=colors[i], ls='--', label='dir2 Delta='+str(Delta_))
plt.legend()
plt.xlabel('Gradient Strength [T/m]')
plt.ylabel('Signal [-]');
```

It can be seen that the two measured perpendicular directions experience slightly different levels of diffusion restriction; the dir2 signal profiles attenuate faster than the dir1 ones. This could implies that that some kind of anisotropic axon dispersion could be happening, or that the axon bundle is slightly tilted towards dir2.

Dmipy allows us to add axon dispersion into the AxCaliber model to compensate for this, but we'll ignore that for this example and fit the signal as-is.

## Fit AxCaliber to spinal cord data

It is known that a Gamma distribution is tricky to fit since there are several parameter combinations that produce similar distributions. We will use the stochastic MIX optimization *(Farooq et al. 2016)*, which is slow but is likely to robustly give the global minimum.

#### NOTE: Fitting AxCaliber to this dataset with MIX takes over 7 hours!

```python
axcaliber_gamma_fit = axcaliber_gamma.fit(
    scheme_spinal_cord, data_spinal_cord.signal,
    mask=data_spinal_cord.mask, solver='mix', maxiter=100)
```

    Using parallel processing with 8 workers.
    Setup MIX optimizer in 4.57763671875e-05 seconds
    Fitting of 968 voxels complete in 30356.3031921 seconds.
    Average of 31.3598173473 seconds per voxel.

## Visualize fitted parameter maps

We can visualize the fitted parameters as before:

```python
fitted_parameters = axcaliber_gamma_fit.fitted_parameters

fig, axs = plt.subplots(2, 3, figsize=[15, 10])
axs = axs.ravel()

counter = 0
for name, values in fitted_parameters.items():
    cf = axs[counter].imshow(values.squeeze().T, origin=True, interpolation='nearest')
    axs[counter].set_title(name)
    axs[counter].set_axis_off()
    fig.colorbar(cf, ax=axs[counter], shrink=0.5)
    counter += 1
```

We can see that the maps for alpha and beta are not super smooth. This could be because we're actually fitting two signals experiencing different restriction levels at the same time, but hard to say without fitting each signal separately. We can visualize the distributions themselves as follows:

```python
axcaliber_alpha = axcaliber_gamma_fit.fitted_parameters['DD1GammaDistributed_1_DD1Gamma_1_alpha']
axcaliber_beta = axcaliber_gamma_fit.fitted_parameters['DD1GammaDistributed_1_DD1Gamma_1_beta']

from dmipy.distributions.distributions import DD1Gamma
gamma = DD1Gamma()

x = 15 # some x-pos in the data
y = 25 # some y-pos in the data

alpha = axcaliber_alpha[x, y, 0]
beta = axcaliber_beta[x, y, 0]

radii, Pgamma = gamma(alpha=alpha, beta=beta)
plt.plot(2 * radii * 1e6, Pgamma)
plt.xlabel('cylinder diameter [$\mu$m]')
plt.ylabel('Gamma probability density')
plt.title('Estimated Gamma distribution');
```

## Comparison between estimated and histology axon diameter

The mean axon diameter can be estimated from the axon diameter distribution as diameter = 2$\alpha\beta$. We compare the histological axon diameter with the estimated ones:

```python
mean_diameter = 2 * axcaliber_alpha * axcaliber_beta * 1e6  # in microns
mean_diameter_histology = data_spinal_cord.histology.h1_axonEquivDiameter  # was already in microns
```

```python
fig, [ax1, ax2] = plt.subplots(1, 2, figsize=[10, 5])

ax1plot = ax1.imshow(mean_diameter.squeeze().T,
           origin=True, vmax=6, interpolation='nearest')
ax1.set_title('Estimated Mean Axon Diameter')
ax1.set_axis_off()
plt.colorbar(ax1plot, ax=ax1, shrink=0.75)

ax2plot = ax2.imshow(mean_diameter_histology.T,
           origin=True, vmax=6, interpolation='nearest')
ax2.set_title('Histology Mean Axon Diameter')
ax2.set_axis_off()
plt.colorbar(ax2plot, ax=ax2, shrink=0.75)
```

We can see that our estimated mean axon diameter map is completely smooth, aside from a few outliers in areas which actually lie outside of the white matter area (see right histology image). The estimated diameters are overestimated in general. We find between 4-6 $\mu$m, while the histological values are between 0-5 $\mu$m.

Using the Seaborn package, we can nicely visualize the correlation between our estimated and the histology diameters. We separate visualize this correlation of axon diameters between 1-2$\mu$m, 2-3$\mu$m and 3+$\mu$m, and remove the exceptional outliers.

```python
mean_diameter_mask12 = np.all([mean_diameter_histology > 1,
                               mean_diameter_histology < 2,
                               mean_diameter.squeeze() < 10], axis=0)
mean_diameter_mask23 = np.all([mean_diameter_histology > 2,
                               mean_diameter_histology < 3,
                               mean_diameter.squeeze() < 10], axis=0)
mean_diameter_mask3p = np.all([mean_diameter_histology > 3,
                               mean_diameter.squeeze() < 10], axis=0)
```

### Axon diameter correlation 1-2 $\mu$m - not significant

```python
import seaborn as sns
mask = mean_diameter_mask12
im = sns.jointplot(mean_diameter[mask].squeeze(),
                   mean_diameter_histology[mask].squeeze(), kind="reg")
im.set_axis_labels("Estimated Axon Diameter", "Histology Axon Diameter", fontsize=15)
```

### Axon diameter correlation 2-3 $\mu$m - not significant

```python
mask = mean_diameter_mask23
im = sns.jointplot(mean_diameter[mask].squeeze(),
                   mean_diameter_histology[mask].squeeze(), kind="reg", color='r')
im.set_axis_labels("Estimated Axon Diameter", "Histology Axon Diameter", fontsize=15)
```

### Axon diameter correlation 3+ $\mu$m - Significant

```python
mask = mean_diameter_mask3p
im = sns.jointplot(mean_diameter[mask].squeeze(),
                   mean_diameter_histology[mask].squeeze(), kind="reg", color='g')
im.set_axis_labels("Estimated Axon Diameter", "Histology Axon Diameter", fontsize=15)
```

The results show that for our current approach to the data set we can only estimate axon diameters that correlate with the histology values for axon diameters of 3+$\mu$m.

## Comparison between estimated and histology volume fraction

Similarly, we can also visualize the estimated intra-axonal volume fraction between our model and the histology values.

```python
axcaliber_fraction = axcaliber_gamma_fit.fitted_parameters['partial_volume_1'].squeeze()
histology_fraction = data_spinal_cord.histology.h4_fr
```

```python
fig, [ax1, ax2] = plt.subplots(1, 2, figsize=[10, 5])

ax1plot = ax1.imshow(axcaliber_fraction.T,
           origin=True,interpolation='nearest', vmax=0.55)
ax1.set_title('Estimated Volume Fraction')
ax1.set_axis_off()
plt.colorbar(ax1plot, ax=ax1, shrink=0.75)

ax2plot = ax2.imshow(histology_fraction.T,
           origin=True, interpolation='nearest', vmax=0.55)
ax2.set_title('Histology Volume Fraction')
ax2.set_axis_off()
plt.colorbar(ax2plot, ax=ax2, shrink=0.75)
```

```python
im = sns.jointplot(axcaliber_fraction[mean_diameter_histology > 1],
              histology_fraction[mean_diameter_histology > 1], kind="reg", color='y')
im.set_axis_labels("Estimated Volume Fraction", "Histology Volume Fraction", fontsize=15);
```

The results show that estimating intra-axonal volume fractions that correlate with histology is easier than doing the same for axon diameter. However, the model does systematically underestimate the value compared to histology.

## References
- Assaf, Yaniv, et al. "AxCaliber: a method for measuring axon diameter distribution from diffusion MRI." Magnetic resonance in medicine 59.6 (2008): 1347-1354.
- Burcaw, Lauren M., Els Fieremans, and Dmitry S. Novikov. "Mesoscopic structure of neuronal tracts from time-dependent diffusion." NeuroImage 114 (2015): 18-37.
- De Santis, Silvia, Derek K. Jones, and Alard Roebroeck. "Including diffusion time dependence in the extra-axonal space improves in vivo estimates of axonal diameter and density in human white matter." NeuroImage 130 (2016): 91-103.
- Farooq, Hamza, et al. "Microstructure imaging of crossing (MIX) white matter fibers from diffusion MRI." Scientific reports 6 (2016): 38927.
- Huang, Susie Y., et al. "The impact of gradient strength on in vivo diffusion MRI estimates of axon diameter." NeuroImage 106 (2015): 464-472.


# Differential UWB model

The ideas behind this model improve on the previous ones by adding a second UWB transceiver to the system. The idea is to be able to measure heading directly from the UWB beacon.

Assumptions:

* Robot moves in the 2D plane
* Gyro in the yaw axis
* Gyroscope has constant bias ($b_\omega$) and random noise.
* UWB receivers are separated by a fixed distance $d$.

As previously, the state of the robot is:

\begin{equation}
\mathbf{x} = \begin{pmatrix}
    x\\
    y\\
    \dot{x}\\
    \dot{y}\\
    \theta\\
    b_{\omega}
    \end{pmatrix}
\end{equation}

```python
import sympy as sp
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
sp.init_printing()

# defines useful variables
x, y, xdot, ydot, theta, b_omega, d = sp.symbols('x y v_x v_y theta b_{\omega} d')
state = sp.Matrix([x, y, xdot, ydot, theta, b_omega])
dt = sp.symbols('Delta_t')
```

# Prediction step

The prediction step is the same as in the gyro integrating model.

```python
a_x, a_y, omega = sp.symbols('a_x a_y omega') # in body frame
u = [a_x, a_y, omega]
dx = sp.Matrix([xdot,
                ydot,
                sp.cos(theta) * a_x - sp.sin(theta) * a_y,
                sp.sin(theta) * a_x + sp.cos(theta) * a_y,
                omega - b_omega,
                0])
g = state + dt * dx
```

## Measurement step

For the measurement, the UWB system gives us the distance $d$ to a beacon.
The beacon's position $\mathbf{b}$ is known and assumed to be fixed.

We first compute the position of each UWB receiver. Receiver $n$ is assumed to be at position $\mathbf{x}_{UWB,n}^R$ in robot frame.

\begin{equation}
\mathbf{x}_{UWB,n}^W = \mathbf{x}_{robot}^W + \begin{pmatrix}
\cos \theta & - \sin \theta \\
\sin \theta & \cos \theta
\end{pmatrix} \mathbf{x}_{UWB,n}^R
\end{equation}

Then the measurement model is:

\begin{equation}
h_n(\mathbf{x}, \mathbf{b}) = \sqrt{(x_{UWB,n}^W - b_x)^2 + (y_{UWB,n}^W - b_y)^2}
\end{equation}

```python
b_x, b_y = sp.symbols('b_x b_y') # beacon position
uwb_x, uwb_y = sp.symbols('x_{UWB} y_{UWB}')
uwb_pos_robot = sp.Matrix([uwb_x, uwb_y])
uwb_pos_world = sp.Matrix([x, y]) + sp.Matrix([[sp.cos(theta), -sp.sin(theta)], [sp.sin(theta), sp.cos(theta)]]) @ uwb_pos_robot
h_b = sp.sqrt((uwb_pos_world[0] - b_x)**2 + (uwb_pos_world[1] - b_y)**2)
#h_b = h_b.replace(uwb_x, 0).replace(uwb_y, 0)
```

```python
# Put it in a matrix to conform with EKF framework
h_b = sp.Matrix([h_b])
```

## EKF implementation

As before, we derive the calculation using Sympy:

```python
g
```

```python
g.jacobian(state)
```

```python
h_b
```

```python
h_b.jacobian(state)
```

## Simulation

```python
f = 200 # Hz, sample rate of the filter
g_num = sp.lambdify([state, u], g.replace(dt, 1/f), 'numpy')
G_num = sp.lambdify([state, u], g.jacobian(state).replace(dt, 1/f), 'numpy')
h_num = sp.lambdify([[b_x, b_y], [uwb_x, uwb_y], state], h_b, 'numpy')
H_num = sp.lambdify([[b_x, b_y], [uwb_x, uwb_y], state], h_b.jacobian(state), 'numpy')
```

```python
# quick sanity checks
s = np.array([1, 1, 0, 0, 3.14, 0])
h_num((0, 0), (1, 1), s)
u = np.array([0, 0 ,0])
g_num(s, u)
g.jacobian(state).replace(dt, 1)
```

```python
# Defines the kalman filter
import functools
import ekf

# Create a dummy variance model
R = np.diag([0.1, # pos
             0.1,
             1e-4, # speed
             1e-4,
             1e-4, # angle
             1e-4  # bias
            ])
Q = np.diag([0.03]) # distance measurement

predictor = ekf.Predictor(g_num, G_num, R)

BEACON_POS = [
    (-1.5, 0),
    (1.5, 1),
    (1.5, -1),
]

d = 0.1# Distance between receivers, in meters
UWB_POS = [
    (-d / 2, 0),
    ( d / 2, 0)
]

correctors = [
    ekf.Corrector(functools.partial(h_num, pos, uwb_pos),
                  functools.partial(H_num, pos, uwb_pos),
                  Q
                 )
for pos in BEACON_POS for uwb_pos in UWB_POS]
```

```python
# Runs the kalman filter on a circular trajectory
import trajectories

f_uwb = 10 # Update frequency for the UWB beacons

bias = np.deg2rad(5) # rad / s
bias_var = np.deg2rad(3.3)

mu = np.array([0, 0, 0, 0.1, 0, bias]) # initial state
sigma = np.diag([1e-1, 1e-1, # pos
                 1e-3, 1e-3, # speed
                 1e-1, # angle
                 bias_var,
                ])

angle, angle_estimated = [], []
x, xhat = [], []
y, yhat = [], []
acc = []
ts = []

for i, p in zip(range(10000), trajectories.generate_circular_traj(1, np.deg2rad(10), 1/f)):

    # add noise & bias to the measurements
    acc = [p.acc[0], p.acc[1]] + np.random.normal(0, 0.2, 2)
    omega = p.omega + np.random.normal(bias, np.sqrt(bias_var))

    # feeds the input into Kalman
    filter_input = np.array([acc[0], acc[1], omega])

    mu, sigma = predictor(mu, sigma, filter_input)

    # If we received a radio update, feed it into the EKF
    if i % (f // f_uwb) == 0:
        for corrector in correctors:
            z = corrector.h(np.array([p.pos[0], p.pos[1], 0, 0, p.theta, 0]))
            z += np.random.normal(0, 0.03)
            mu, sigma = corrector(mu, sigma, z)

    # Saves the data
    ts.append(p.timestamp)
    angle.append(p.theta)
    angle_estimated.append(mu[4])
    x.append(p.pos[0])
    xhat.append(mu[0])
    y.append(p.pos[1])
    yhat.append(mu[1])
```

```python
# Plot various results
rms = np.sqrt(np.mean([(a - b)**2 for a, b in zip(angle, angle_estimated)]))
plt.plot(ts, np.degrees(angle))
plt.plot(ts, np.degrees(angle_estimated))
plt.xlabel('time [s]')
plt.ylabel('heading [degrees]')
plt.legend(['truth', 'estimated'])
plt.title('Theta (RMS={:.2f}°)'.format(np.degrees(rms)))
plt.gcf().savefig('differential_model_angle.pdf')
plt.show()

plt.plot(ts, x)
plt.plot(ts, xhat)
plt.plot(ts, y)
plt.plot(ts, yhat)
plt.xlabel('time')
plt.ylabel('meters')
plt.title('position')
plt.legend(['x', 'x (estimated)', 'y', 'y (estimated)'])
plt.show()

plt.plot(x, y)
plt.plot(xhat, yhat)
plt.plot([x for x, y in BEACON_POS],[y for x, y in BEACON_POS], 'x')
plt.legend(('Simulated trajectory', 'EKF output', 'anchors'))
plt.title('trajectory')
plt.xlabel('x [m]')
plt.ylabel('y [m]')
plt.gcf().savefig('differential_model_trajectory.pdf')
plt.show()

error = [np.sqrt((x-xh)**2+(y-yh)**2) for x,xh,y,yh in zip(x, xhat,y,yhat)]
plt.plot(ts, error)
plt.xlabel('time [s]')
plt.ylabel('position error [m]')
plt.title('Position error (RMS = {:.3f} m)'.format(np.mean(error)))
plt.ylim(0, 0.1)
plt.gcf().savefig('differential_model_error.pdf')

plt.show()
```

```python

```


```python
# Header starts here.
from sympy.physics.units import *
from sympy import *

# Rounding:
import decimal
from decimal import Decimal as DX
from copy import deepcopy
def iso_round(obj, pv, rounding=decimal.ROUND_HALF_EVEN):
    import sympy
    """
    Rounding acc. to DIN EN ISO 80000-1:2013-08
    place value = Rundestellenwert
    """
    assert pv in set([
        # place value   #  round to:
        1,              #  1
        0.1,            #  1st digit after decimal
        0.01,           #  2nd
        0.001,          #  3rd
        0.0001,         #  4th
        0.00001,        #  5th
        0.000001,       #  6th
        0.0000001,      #  7th
        0.00000001,     #  8th
        0.000000001,    #  9th
        0.0000000001,   # 10th
        ])
    objc = deepcopy(obj)
    try:
        tmp = DX(str(float(objc)))
        objc = tmp.quantize(DX(str(pv)), rounding=rounding)
    except:
        for i in range(len(objc)):
            tmp = DX(str(float(objc[i])))
            objc[i] = tmp.quantize(DX(str(pv)), rounding=rounding)
    return objc

# LateX:
kwargs = {}
kwargs["mat_str"] = "bmatrix"
kwargs["mat_delim"] = ""
# kwargs["symbol_names"] = {FB: "F^{\mathsf B}", }

# Units:
(k, M, G ) = ( 10**3, 10**6, 10**9 )
(mm, cm) = ( m/1000, m/100 )
Newton = kg*m/s**2
Pa     = Newton/m**2
MPa    = M*Pa
GPa    = G*Pa
kN     = k*Newton
deg    = pi/180

half = S(1)/2

# Header ends here.
#
# https://colab.research.google.com/github/kassbohm/tm-snippets/blob/master/ipynb/TM_A/TM_0/trafo_tensor/trafo_tensor_0_cc.ipynb

f = lambda x: iso_round(x,prec)

"""
    Input:

    * (x,y)-Components of Symm. Tensor.
    * Angular Position phi.
    * Output Precision prec.

    Output:
    * (\bar x, \bar y)`-Components for given phi.
    * Principal values and resp. angles.

"""
# User input starts here.
prec = 0.01

# Tensor components in their resp. unit:

# Txx, Txy, Tyy = var("Txx, Txy, Tyy")
(Txx, Txy, Tyy)  = ( -1,  4,  5)
# (Txx, Txy, Tyy)  = (-12, -6,  0)
# (Txx, Txy, Tyy)  = ( -2, -6,  9)
(Txx, Txy, Tyy)  = ( 13,  -4,  7)
# (Txx, Txy, Tyy)  = (-1.2, -0.6,  0)
# (Txx, Txy, Tyy)  = (864, 0,  216)

# Angle in deg:
phi = 120

# User input ends here.

pprint("\nφ / deg:")
tmp = phi
pprint(tmp)

print(u'\nComponents wrt (x, y):')
T = Matrix([ [Txx, Txy], [Txy, Tyy] ])
pprint(T)

pprint("\nR:")
phi *= pi/180
c, s = cos(phi), sin(phi)
R = Matrix([ [c, s] , [-s, c] ])
tmp = R

tmp = tmp.applyfunc(f)
pprint(tmp)

pprint(u"\nComponents wrt (x\u0304, y\u0304):")

Rt = R.transpose()
tmp = R*T*Rt
tmp = tmp.applyfunc(simplify)
tmp = tmp.applyfunc(f)
pprint(tmp)

pprint("\n(λ₁, λ₂):")
ev = T.eigenvals()
tmp = Matrix([max(ev), min(ev)])
tmp = tmp.applyfunc(f)
pprint(tmp)

pprint("\n(φ₁, φ₂) / deg:")
t1 = Txy
t2 = (Txx - min(ev))
if (t1==0 and Txx < Tyy):
    p1 = pi/2
else:
    p1 = atan(t1/t2)
p1 *= 180/pi
p2 = p1 + 90
p = Matrix([iso_round(p1,prec), iso_round(p2,prec)])
pprint(p)

# Components wrt (x, y):
# ⎡-1  4⎤
# ⎢     ⎥
# ⎣4   5⎦
#
# Components wrt (x̄, ȳ) for φ = 30.00 deg:
# ⎡3.96  4.6 ⎤
# ⎢          ⎥
# ⎣4.6   0.04⎦
#
# (λ₁, λ₂):
# ⎡7.0 ⎤
# ⎢    ⎥
# ⎣-3.0⎦
#
# (φ₁, φ₂) / deg:
# ⎡63.43 ⎤
# ⎢      ⎥
# ⎣153.43⎦

```


# Map, Filter, Reduce, and Groupby

本部分展示高阶函数应用

```python
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

```python
def square(x):
    return x ** 2

def iseven(n):
    return n % 2 == 0

def add(x, y):
    return x + y

def mul(x, y):
    return x * y

def lesser(x, y):
    if x < y:
        return x
    else:
        return y

def greater(x, y):
    if x > y:
        return x
    else:
        return y
```

## Map

```python
# map works like this
list(map(square, data))
```

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

```python
# In this way it's like numpy's broadcasting operators
import numpy as np
X = np.arange(1, 11)
X*2
```

    array([ 2,  4,  6,  8, 10, 12, 14, 16, 18, 20])

但是 `map` 是纯python函数，所以

*   很慢
*   能够处理普通的函数比如fibonacci

```python
def fib(i):
    if i in (0, 1):
        return i
    else:
        return fib(i - 1) + fib(i - 2)

list(map(fib, data))
```

    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

```python
# 通过情况下，我们将会这样应用他们
result = []
for item in data:
    result.append(fib(item))

result
```

    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

```python
# 查看下上面给的好的范式说明了如何定义一个map方法 map looking at the function above gives us a good pattern for how to define `map`
# 我们将自己抽象定义一个map函数  We just abstract out the function `fib` for a user input

# `map` is easy to define
def map(fn, sequence):
    result = []
    for item in sequence:
        result.append(fn(item))
    return result
```

鲜为人知的事实是，对象的方法也是完全有效的函数

```python
map(str.upper, ['Alice', 'Bob', 'Charlie'])
```

    ['ALICE', 'BOB', 'CHARLIE']

map函数是非常重要的，它有自己的语法，**列表理解**，

```python
[fib(i) for i in data]
```

    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

```python
[name.upper() for name in ['Alice', 'Bob', 'Charlie']]
```

    ['ALICE', 'BOB', 'CHARLIE']

## Filter

“过滤器” 高阶函数通过断言方式来过滤数据集。

断言是一个返回“True”或“False”的函数。 `filter`函数返回一个新的只有断言为true的元素的列表。

```python
list(filter(iseven, data))
```

    [2, 4, 6, 8, 10]

```python
from sympy import isprime  # Only works if you have the sympy math library installed
list(filter(isprime, data))
```

    [2, 3, 5, 7]

```python
def filter(predicate, sequence):
    result = []
    for item in sequence:
        if predicate(item):
            result.append(item)
    return result
```

## Reduce

Reduce是`map`和`filter`的小兄弟。 Reduce不太受欢迎，经常被责骂难以理解。

尽管社会问题“Reduce”是相当强大的，一旦你写了“Reduce”，一旦你明白它是如何工作的。 更重要的是，您将学习如何识别约简操作以及如何将它们与二元运算符配对。 数据分析中的降维操作很常见的，特别是在将大型数据集缩减为概要时。

为了显示“Reduce”，我们将首先实现两个常见的减少，“sum”和“min”。 我们已经用二元运算符`add`和`lessser`来暗示它们，以突出它们的类似结构。 选出以下两个互不相同功能的部分。

```python
def sum(sequence):
    result = 0
    for item in sequence:
        # reult = result + item
        result = add(result, item)
    return result
```

```python
def min(sequence):
    result = 99999999999999  # a really big number
    for item in sequence:
        # result = result if result < item else item
        result = lesser(result, item)
    return result
```

### Exercise

现在填写下面的空白来完成`product`的定义，这个函数将序列的元素放在一起。

```python
def product(sequence):
    result = ?
    for item in sequence:
        result = ?(result, item)
    return result

assert product([2, 3, 10]) == 60
```

### Exercise

实现 `reduce`.

首先复制上述三个函数的模式。 三者之间的差异是你的输入。 传统上，reduce的论点是有序的，以便下面的例子运行良好。

```python
def reduce(...):
    ...
```

```python
from functools import reduce
reduce(add, data, 0)
```

    55

```python
reduce(mul, data, 1)
```

    3628800

```python
reduce(lesser, data, 10000000)
```

    1

```python
reduce(greater, data, -100000000)
```

    10

## Lambda

我们这部分课程有很多像这样小的函数定义

```
def add(x, y):
    return x + y
```

这些单线功能有时看起来有点愚蠢。 我们使用`lambda`关键字来即时创建小函数。 上述定义可以表述如下

```
add = lambda x, y: x + y
```

表达式`lambda x，y：x + y`是一个值，就像`3`或`Alice`一样。 就像文字整数和字符串一样，Lambda表达式可以在不用变量存储的情况下即时使用。

```python
reduce(add, data, 0)
```

    55

```python
reduce(lambda x, y: x + y, data, 0)  # Define `add` on the fly
```

    55

另外，我们可以使用`lambda`来快速指定函数作为更一般化的特化。 在下面我们快速定义总和，最小值和最大值。

```python
sum = lambda data: reduce(add, data, 0)
min = lambda data: reduce(lesser, data, 99999999999)
max = lambda data: reduce(greater, data, -999999999999)
```

```python
sum(data)
```

    55

作业练习，自己定制一个 `product` 使用下 `lambda`, `reduce`, 和 `mul`.

```python
product = ...
assert product([2, 3, 10]) == 60
```

## Groupby

Groupby可以被看作是“filter”的一个更强大的版本。 而不是给你一个数据的子集，它把数据分成所有相关的子集。

```python
filter(iseven, data)
```

    [2, 4, 6, 8, 10]

```python
from toolz import groupby
groupby(iseven, data)
```

    {False: [1, 3, 5, 7, 9], True: [2, 4, 6, 8, 10]}

```python
groupby(isprime, data)
```

    {False: [1, 4, 6, 8, 9, 10], True: [2, 3, 5, 7]}

但是 `groupby` 不能严格的断言 (传递函数返回 `True` 或 `False`)

```python
groupby(lambda n: n % 3, data)
```

    {0: [3, 6, 9], 1: [1, 4, 7, 10], 2: [2, 5, 8]}

```python
groupby(len, ['Alice', 'Bob', 'Charlie', 'Dan', 'Edith', 'Frank'])
```

    {3: ['Bob', 'Dan'], 5: ['Alice', 'Edith', 'Frank'], 7: ['Charlie']}

令人惊讶的是`groupby`在普通情况下并不比`filter` 消费更多资源。 它通过数据一次性计算这些数据组。

## Integrative example

让我们把它们放在一个小数据集中展示。

```python
likes = """Alice likes Chocolate
Bob likes Chocolate
Bob likes Apples
Charlie likes Apples
Alice likes Peanut Butter
Charlie likes Peanut Butter"""
```

```python
tuples = map(lambda s: s.split(' likes '), likes.split('\n'))
tuples
```

    <map at 0xe5f2c88>

```python
groups = groupby(lambda x: x[0], tuples)
groups
```

    {'Alice': [['Alice', 'Chocolate'], ['Alice', 'Peanut Butter']],
     'Bob': [['Bob', 'Chocolate'], ['Bob', 'Apples']],
     'Charlie': [['Charlie', 'Apples'], ['Charlie', 'Peanut Butter']]}

```python
from toolz import valmap, first, second
valmap(lambda L: list(map(second, L)), groups)
```

    {'Alice': ['Chocolate', 'Peanut Butter'],
     'Bob': ['Chocolate', 'Apples'],
     'Charlie': ['Apples', 'Peanut Butter']}

```python
tuples = map(lambda s: s.split(' likes '), likes.split('\n'))
valmap(lambda L: list(map(first, L)), groupby(lambda x: x[1], tuples))
```

    {'Apples': ['Bob', 'Charlie'],
     'Chocolate': ['Alice', 'Bob'],
     'Peanut Butter': ['Alice', 'Charlie']}

```python
tuples = list(map(lambda s: s.split(' likes '), likes.split('\n')))
# first second 取数据
# groupby 数据分组
# compose 函数组合
# valmap 字典元组计算
from toolz.curried import map, valmap, groupby, first, second, get, curry, compose, pipe

f = compose(valmap(first), groupby(second))

f(tuples)
```

    {'Apples': ['Bob', 'Apples'],
     'Chocolate': ['Alice', 'Chocolate'],
     'Peanut Butter': ['Alice', 'Peanut Butter']}

```python

```


```python
%load_ext autoreload
%autoreload 2
import sympy as smp
import numpy as np
import scipy.special as sp

import matplotlib
matplotlib.rcParams['pdf.fonttype'] = 42
matplotlib.rcParams['ps.fonttype'] = 42

import matplotlib.pyplot as plt
%matplotlib inline

import seaborn as sns
color_names = ["windows blue",
               "red",
               "gold",
               "grass green"]
colors = sns.xkcd_palette(color_names)
sns.set_style("white")
```

```python
def logQ_grep(eps,alpha):
    sqrt_poly = np.sqrt(sp.polygamma(1,alpha))
    norm_const = 0.5*np.log(sp.polygamma(1,alpha)) + alpha*sp.digamma(alpha)-sp.gammaln(alpha)
    exp_term = np.exp(eps*sqrt_poly + sp.digamma(alpha))
    return eps*alpha*sqrt_poly - exp_term + norm_const

def derH_eps(eps,alpha):
    b = alpha-1./3.
    c = 1./np.sqrt(9.*b)
    v = 1.+eps*c

    return 3.*b*c*(v**2)

def fun_H(eps,alpha):
    b = alpha-1./3.
    c = 1./np.sqrt(9.*b)
    v = 1.+eps*c

    return b*v**3

def Q_rej(eps,alpha):
    b = alpha-1./3.
    c = np.sqrt(9.*b)
    norm_const = -sp.gammaln(alpha)
    Q = np.zeros_like(eps)
    t_1 = (alpha-1.)*np.log(fun_H(eps[eps>-c],alpha))
    t_2 = -fun_H(eps[eps>-c],alpha)+np.log(np.abs(derH_eps(eps[eps>-c],alpha)))
    Q[eps>-c] = np.exp(t_1+t_2+norm_const)
    return Q

alphas = [1.0,2.0,10.0]
epsilon = np.linspace(-3.,3.,100)

fig = plt.figure(figsize=(16, 4))
ax = fig.add_subplot('131')
iter_ind = 0
for alpha in alphas:
    iter_ind += 1
    ax = fig.add_subplot('13'+str(iter_ind))
    ax.plot(epsilon,np.exp(-0.5*epsilon**2)/np.sqrt(2.*np.pi),'k--',lw=4, label='$\\mathcal{N}(0,1)$')
    ax.plot(epsilon,np.exp(logQ_grep(epsilon,alpha)),color=colors[0],lw=4, label='$\\mathrm{G-REP}$')
    if alpha < 1.:
        alpha_rej = alpha+1.
    else:
        alpha_rej = alpha
    ax.plot(epsilon,Q_rej(epsilon,alpha_rej),color = colors[1],lw=4, label='$\\mathrm{RSVI}$')
    ax.tick_params(axis='both', which='major', labelsize=16)
    ax.tick_params(axis='both', which='minor', labelsize=16)
    ax.set_xlabel("$\\varepsilon$", fontsize=28)
    ax.set_title('$\\mathbf{\\alpha} = '+str(alpha)+'$',fontsize=18)
    plt.yticks([0.0,0.1,0.2,0.3,0.4,0.5], [0.0,0.1,0.2,0.3,0.4,0.5])
lgd = ax.legend(fontsize=18,bbox_to_anchor=(0.1, 0.6, 1.5, 0.102))
#plt.tight_layout()
filename = './compare_Qeps.pdf'
plt.savefig(filename, bbox_extra_artists=(lgd,), bbox_inches='tight', dpi=300)
```

```python

```


$\newcommand{\xv}{\mathbf{x}}
 \newcommand{\wv}{\mathbf{w}}
 \newcommand{\vv}{\mathbf{v}}
 \newcommand{\yv}{\mathbf{y}}
 \newcommand{\zv}{\mathbf{z}}
 \newcommand{\av}{\mathbf{a}}
 \newcommand{\Chi}{\mathcal{X}}
 \newcommand{\R}{\rm I\!R}
 \newcommand{\sign}{\text{sign}}
 \newcommand{\Tm}{\mathbf{T}}
 \newcommand{\Xm}{\mathbf{X}}
 \newcommand{\Xlm}{\mathbf{X1}}
 \newcommand{\Wm}{\mathbf{W}}
 \newcommand{\Vm}{\mathbf{V}}
 \newcommand{\Ym}{\mathbf{Y}}
 \newcommand{\Zm}{\mathbf{Z}}
 \newcommand{\Gm}{\mathbf{G}}
 \newcommand{\Zlm}{\mathbf{Z1}}
 \newcommand{\I}{\mathbf{I}}
 \newcommand{\muv}{\boldsymbol\mu}
 \newcommand{\Sigmav}{\boldsymbol\Sigma}
 \newcommand{\Phiv}{\boldsymbol\Phi}
$

# Nonlinear Logistic Regression

Previously, we learned the linear logistic regression that uses the softmax layer for classification along with a linear model.

$$
g_k(\xv) = P(T=k \mid \xv) = \frac{e^{\kappa_k}}{\sum_{c=1}^K e^{\kappa_c}}
$$

By using this softmax function, we were able to generate probablistic outputs for all classes. To handle multi-label classes, we use the indicator target labels for training to update the weights for the linear model.
Following the derivation, we have achieved the following update rule:

$$
\wv_j \leftarrow \wv_j + \alpha \sum_{n=1}^{N} \Big( t_{n,j} - g_j(\xv_n)\Big) \xv_n.
$$

To update the weights with batch samples, we can convert this update rule in matrix form as follows:

$$
\wv \leftarrow \wv + \alpha \Xm^\top \Big(  \Tm - g(\Xm)\Big).
$$

Remember we start from the error function below for the derivation bvefore:

$$
E(\wv) = - \ln P(\Tm \mid \wv) =  - \sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} \ln y_{n,k}.
$$

# Nonlinear Extension with Neural Networks

Now, we extend this to two layer neural networks. Similar to the derivation of neural network for regression, we can derive the gradient by switching the squuared error with the negative log likelihood function above.

From the error function $E(\wv)$, we can derive the gradient to update the weights for each layer.

$$
\begin{align}
v_{dg} &\leftarrow v_{dg} - \alpha_h \frac{\partial{E(\Wm, \Vm)}} {\partial{v_{dg}}} \\
\\
w_{gk} &\leftarrow w_{gk} - \alpha_o \frac{\partial{E(\Wm, \Vm)}} {\partial{w_{gk}}},
\end{align}
$$

where $\alpha_h$ and $\alpha_o$ are the learning rate for hidden and output layer respectively. Here, we denote the output of the neural network as $\kappa$.

$$
\begin{align}
\frac{\partial{E}}{\partial{w_{gk}}} &= -\frac{\partial{\Big( \sum_{n=1}^{N} \sum_{l=1}^{K} (t_{nl} \ln g_{nl}(\xv_n))} \Big)}{\partial{w_{gk}}} \\
   \\
    &= -\sum_{n=1}^{N} \sum_{l=1}^{K} t_{n,l} \frac{1}{g_{n,k}(\xv_n)} \frac{\partial g_{n,k}(\xv_n)}{\partial  {w_{gk}}}\\
    &= -\sum_{n=1}^{N} \sum_{l=1}^{K} t_{n,l} \frac{1}{g_{n,k}(\xv_n)} \frac{\partial g_{n,k}(\xv_n)}{\partial  \kappa_{nk}} \frac{\partial  \kappa_{nk} }{\partial  {w_{gk}}}\\
    &= -\sum_{n=1}^{N} \sum_{l=1}^{K} t_{n,l} \frac{1}{g_{n,k}(\xv_n)} g_{nk}(\xv_n) (I_{lk} - g_{nk}(\xv_n))  \frac{\partial  \kappa_{nk} }{\partial  {w_{gk}}}\\
    &= -\sum_{n=1}^{N} \sum_{l=1}^{K} t_{n,l} (I_{lk} - g_{nk}(\xv_n))  \frac{\partial  \sum_{g=0}^{G} z1_{ng} w_{gk}  }{\partial  {w_{gk}}}\\
    &= -\sum_{n=1}^{N} \sum_{l=1}^{K} t_{n,l} (I_{lk} - g_{nk}(\xv_n)) z1_{ng}\\
    &= -\sum_{n=1}^{N} \Big(\sum_{l=1}^{K}  t_{n,l} (I_{lk} - g_{nk}(\xv_n)) \Big) z1_{ng}\\
    &= -\sum_{n=1}^{N} \Big( \sum_{l=1}^{K} t_{n,l} I_{lk} - g_{nk}(\xv_n) \sum_{l=1}^{K} t_{n,l}  \Big) z1_{ng}\\
    &= -\sum_{n=1}^{N} \Big( t_{n,k} - g_{nk}(\xv_n) \Big) z1_{ng}.
\end{align}
$$

Coverting this gradient in matrix form and reflecting it on our weight update,

$$
\Wm \leftarrow \Wm + \alpha_o \Zlm^\top \Big(  \Tm - g(\Xm)\Big).
$$

Now let us update the weight $\vv$ for the hidden layer.
For the hidden layer, we repeat this:

$$
\begin{align}
\frac{\partial{E}}{\partial{v_{dg}}} &= \frac{\partial{\Big( \sum_{n=1}^{N} \sum_{k=1}^{K} (t_{nk} \ln g_{nk}(\xv_n))}  \Big)}{\partial{v_{dg}}} \\
    &= -\sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} \frac{1}{g_{n,k}(\xv_n)} \frac{\partial g_{n,k}(\xv_n)}{\partial  {v_{dg}}}\\
    &= -\sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} \frac{1}{g_{n,k}(\xv_n)} \frac{\partial g_{n,k}(\xv_n)} {\partial \kappa_{nk}} \frac{\partial \kappa_{nk}} {\partial  {v_{dg}}}\\
    &= -\sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} \frac{1}{g_{n,k}(\xv_n)} \frac{\partial g_{n,k}(\xv_n)} {\partial \kappa_{nk}} \sum_{g=0}^G w_{gk} \frac{\partial{h(a_{ng})}}{\partial{a_{ng}}} \frac{\partial{a_{ng}}}{\partial{v_{dg}}}\\
    &= -\sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} (I_{kk} - g_{nk}(\xv_n)) \sum_{g=0}^G w_{gl} \frac{\partial{h(a_{ng})}}{\partial{a_{ng}}} \frac{\partial{a_{ng}}}{\partial{v_{dg}}}\\
    &= -\sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} (I_{kk} - g_{nk}(\xv_n)) \sum_{g=0}^G w_{gk} \frac{\partial{h(a_{ng})}}{\partial{a_{ng}}} x1_{nd}\\
    &= -\sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} (I_{kk} - g_{nk}(\xv_n)) \sum_{g=0}^G w_{gk} \frac{\partial{h(a_{ng})}}{\partial{a_{ng}}} x1_{nd}\\
    &= -\sum_{n=1}^{N} \sum_{k=1}^{K} t_{n,k} (I_{kk} - g_{nk}(\xv_n)) \sum_{g=0}^G w_{gk} (1 - z_{ng}^2) x1_{nd}.
\end{align}
$$

Again, coverting in matrix form for the hidden weight update,

$$
\Vm \leftarrow \Vm + \alpha_h \Xlm^\top \Big( (\Tm - g(\Xm)) \Wm^\top \odot (1 - \Zm^2) \Big).
$$

Here, $\odot$ denotes the element-wise multiplication.

## Summary (Regression vs Classification)

 Regression
 Classification

Forward Pass

$$
\begin{align}
\Zm &= h(\Xlm \cdot \Vm) \\
\\
\Ym & = \Zlm \cdot \Wm
\end{align}
$$

$$
\begin{align}
\Zm &= h(\Xlm \cdot \Vm) \\
\\
\Ym & = \Zlm \cdot \Wm \\
\Gm & = softmax(\Ym)
\end{align}
$$

 Backward Pass

$$
\begin{align}
\Vm &\leftarrow \Vm + \alpha_h \frac{1}{N} \frac{1}{K} \Xlm^\top \Big( (\Tm - \Ym) \Wm^\top \odot (1 - \Zm^2) \Big) \\
\Wm &\leftarrow \Wm + \alpha_o \frac{1}{N} \frac{1}{K} \Zlm^\top \Big( \Tm - \Ym \Big)
\end{align}
$$

$$
\begin{align}
\Vm &\leftarrow \Vm + \alpha_h \Xlm^\top \Big( (\Tm - \Gm) \Wm^\top \odot (1 - \Zm^2) \Big)\\
\Wm &\leftarrow \Wm + \alpha_o \Zlm^\top \Big(  \Tm - \Gm\Big)
\end{align}
$$

Note: Here $\Tm$ is a matrix with indicator variable outputs,

and $\Gm$ is the output matrix after the softmax layer.

# Practice

Now, inherit the previous NeuralNetwork class to implement neural network classification.

```python
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

import nn
```

Let us repeat the previous classification example with nonlinear classification.

```python
# Data for testing
N1 = 50
N2 = 50
N = N1 + N2
D = 2
K = 2

mu1 = [-1, -1]
cov1 = np.eye(2)

mu2 = [2,3]
cov2 = np.eye(2) * 3

#
#  Train Data
#
C1 = np.random.multivariate_normal(mu1, cov1, N1)
C2 = np.random.multivariate_normal(mu2, cov2, N2)

plt.plot(C1[:, 0], C1[:, 1], 'or')
plt.plot(C2[:, 0], C2[:, 1], 'xb')

plt.xlim([-3, 6])
plt.ylim([-3, 7])
plt.title("training data set")

Xtrain = np.vstack((C1, C2))
Ttrain = np.zeros((N, 1))
Ttrain[50:, :] = 1  # labels are zero or one

means, stds = np.mean(Xtrain, 0), np.std(Xtrain, 0)
# normalize inputs
Xtrains = (Xtrain - means) / stds

#
#  Test Data
#
Ct1 = np.random.multivariate_normal(mu1, cov1, 20)
Ct2 = np.random.multivariate_normal(mu2, cov2, 20)

Xtest = np.vstack((Ct1, Ct2))
Ttest = np.zeros((40, 1))
Ttest[20:, :] = 1

# normalize inputs
Xtests = (Xtrain - means) / stds

plt.figure()
plt.plot(Ct1[:, 0], Ct1[:, 1], 'or')
plt.plot(Ct2[:, 0], Ct2[:, 1], 'xb')

plt.xlim([-3, 6])
plt.ylim([-3, 7])
plt.title("test data set")

```

```python
# Apply Nonlinear Logistic Regression
from imp import reload
reload(nn)
#import warnings
#warnings.filterwarnings('ignore')

clsf = nn.NeuralNetLogReg([2, 4, 2])
clsf.train(Xtrain, Ttrain)
classes, Y = clsf.use(Xtest)
```

```python
classes
```

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

```python
Y
```

    array([[  1.00000000e+00,   3.62429239e-24],
           [  1.00000000e+00,   4.49791656e-10],
           [  9.99999998e-01,   2.08859210e-09],
           [  1.00000000e+00,   3.62429232e-24],
           [  2.99307336e-01,   7.00692664e-01],
           [  1.00000000e+00,   3.62429229e-24],
           [  1.00000000e+00,   3.62429243e-24],
           [  1.00000000e+00,   3.62926450e-24],
           [  1.00000000e+00,   6.36987730e-24],
           [  1.00000000e+00,   3.62429240e-24],
           [  5.99996498e-01,   4.00003502e-01],
           [  1.00000000e+00,   3.62429229e-24],
           [  1.00000000e+00,   4.48284191e-24],
           [  1.00000000e+00,   3.64360621e-24],
           [  1.00000000e+00,   3.95678934e-24],
           [  1.00000000e+00,   3.67347448e-24],
           [  1.00000000e+00,   3.62429229e-24],
           [  1.00000000e+00,   3.62429233e-24],
           [  1.00000000e+00,   5.59588219e-18],
           [  1.00000000e+00,   3.62429229e-24],
           [  1.71288265e-23,   1.00000000e+00],
           [  2.19935378e-14,   1.00000000e+00],
           [  1.71288265e-23,   1.00000000e+00],
           [  1.71290892e-23,   1.00000000e+00],
           [  1.70788912e-14,   1.00000000e+00],
           [  4.48420430e-14,   1.00000000e+00],
           [  6.00020101e-01,   3.99979899e-01],
           [  1.71594780e-23,   1.00000000e+00],
           [  1.75541816e-23,   1.00000000e+00],
           [  6.04943745e-15,   1.00000000e+00],
           [  4.48184489e-14,   1.00000000e+00],
           [  4.48415004e-14,   1.00000000e+00],
           [  4.37481476e-14,   1.00000000e+00],
           [  1.71532100e-23,   1.00000000e+00],
           [  1.41251835e-13,   1.00000000e+00],
           [  4.28267187e-14,   1.00000000e+00],
           [  4.48414747e-14,   1.00000000e+00],
           [  1.71288265e-23,   1.00000000e+00],
           [  1.71288265e-23,   1.00000000e+00],
           [  5.00047240e-01,   4.99952760e-01]])

```python
# retrieve labels and plot

plt.plot(Ttest)
plt.plot(classes)

print("Accuracy: ", 100 - np.mean(np.abs(Tl - Yl)) * 100, "%")
```

```python
# show me the boundary

x = np.linspace(-3, 6, 1000)
y = np.linspace(-3, 7, 1000)

xs, ys = np.meshgrid(x, y)

X = np.vstack((xs.flat, ys.flat)).T
classes, _ = clsf.use(X)
zs = classes.reshape(xs.shape)

plt.figure(figsize=(6,6))
plt.contourf(xs, ys, zs.reshape(xs.shape))
plt.title("Decision Boundary")

plt.plot(Ct1[:, 0], Ct1[:, 1], 'or')
plt.plot(Ct2[:, 0], Ct2[:, 1], 'xb')

```

```python
from sklearn.datasets import make_circles

X, T = make_circles(n_samples=800, noise=0.07, factor=0.4)

plt.figure(figsize=(10, 8))
plt.scatter(X[:, 0], X[:, 1], marker='o', c=T)
plt.title("Circles")

```

```python
clsf = nn.NeuralNetLogReg([2, 1, 2])
clsf.train(X, T)

# checking the training error only
classes, Y = clsf.use(X)
```

```python
# retrieve labels and plot

plt.plot(T)
plt.plot(classes)

print("Accuracy: ", 100 - np.mean(np.abs(T - classes)) * 100, "%")
```

```python
# show me the boundary

x = np.linspace(-1.5, 1.5, 1000)
y = np.linspace(-1.5, 1.5, 1000)

xs, ys = np.meshgrid(x, y)

Xt = np.vstack((xs.flat, ys.flat)).T
classes, _ = clsf.use(Xt)
zs = classes.reshape(xs.shape)

plt.figure(figsize=(6,6))
plt.contourf(xs, ys, zs.reshape(xs.shape), alpha=0.3)
plt.title("Decision Boundary")

plt.scatter(X[:, 0], X[:, 1], marker='o', c=T+3)

```

```python
from sklearn.datasets import load_iris

data = load_iris()
```

```python
data.keys()
```

    dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])

```python
data.target
```

    array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
           2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
           2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

```python
data.data.shape
```

    (150, 4)

```python
clsf = nn.NeuralNetLogReg([4, 1, 3])
clsf.train(data.data, data.target)

# checking the training error only
classes, Y = clsf.use(data.data)
```

```python
# retrieve labels and plot

plt.plot(data.target)
plt.plot(classes)

print("Accuracy: ", 100 - np.mean(np.abs(data.target - classes)) * 100, "%")
```

```python
Y
```

    array([[  9.99991385e-01,   8.61541898e-06,   2.16892851e-27],
           [  9.99978241e-01,   2.17593859e-05,   1.73875252e-26],
           [  9.99986146e-01,   1.38544096e-05,   6.30606216e-27],
           [  9.99971064e-01,   2.89362302e-05,   3.29887992e-26],
           [  9.99992127e-01,   7.87333680e-06,   1.77158220e-27],
           [  9.99982124e-01,   1.78759977e-05,   1.11795632e-26],
           [  9.99978766e-01,   2.12335059e-05,   1.64576183e-26],
           [  9.99986703e-01,   1.32968101e-05,   5.75011385e-27],
           [  9.99962956e-01,   3.70441567e-05,   5.74627718e-26],
           [  9.99985191e-01,   1.48093898e-05,   7.32482714e-27],
           [  9.99993245e-01,   6.75457274e-06,   1.25551382e-27],
           [  9.99980827e-01,   1.91733484e-05,   1.30853666e-26],
           [  9.99985342e-01,   1.46575442e-05,   7.15717099e-27],
           [  9.99989996e-01,   1.00044561e-05,   3.03453396e-27],
           [  9.99997699e-01,   2.30076932e-06,   1.11687549e-28],
           [  9.99995299e-01,   4.70117860e-06,   5.56182688e-28],
           [  9.99992709e-01,   7.29105849e-06,   1.49071353e-27],
           [  9.99986934e-01,   1.30657238e-05,   5.52802932e-27],
           [  9.99988758e-01,   1.12416319e-05,   3.94324546e-27],
           [  9.99989750e-01,   1.02495403e-05,   3.20410301e-27],
           [  9.99983378e-01,   1.66221586e-05,   9.49442080e-27],
           [  9.99981331e-01,   1.86685265e-05,   1.23239976e-26],
           [  9.99995566e-01,   4.43440123e-06,   4.87770831e-28],
           [  9.99875830e-01,   1.24170250e-04,   8.70150917e-25],
           [  9.99957625e-01,   4.23750801e-05,   7.77272389e-26],
           [  9.99965660e-01,   3.43395579e-05,   4.84634245e-26],
           [  9.99954736e-01,   4.52641786e-05,   9.01421936e-26],
           [  9.99989901e-01,   1.00986885e-05,   3.09912634e-27],
           [  9.99990556e-01,   9.44389535e-06,   2.66581715e-27],
           [  9.99970726e-01,   2.92737336e-05,   3.38595511e-26],
           [  9.99967160e-01,   3.28396227e-05,   4.38365163e-26],
           [  9.99974144e-01,   2.58558431e-05,   2.56177660e-26],
           [  9.99996831e-01,   3.16910051e-06,   2.29314277e-28],
           [  9.99997130e-01,   2.86951379e-06,   1.83458591e-28],
           [  9.99985191e-01,   1.48093898e-05,   7.32482714e-27],
           [  9.99990733e-01,   9.26748328e-06,   2.55523967e-27],
           [  9.99994322e-01,   5.67817825e-06,   8.50057818e-28],
           [  9.99985191e-01,   1.48093898e-05,   7.32482714e-27],
           [  9.99976392e-01,   2.36084880e-05,   2.08842366e-26],
           [  9.99987487e-01,   1.25126585e-05,   5.01613497e-27],
           [  9.99988945e-01,   1.10546501e-05,   3.79741708e-27],
           [  9.99841005e-01,   1.58994538e-04,   1.51643682e-24],
           [  9.99983278e-01,   1.67216522e-05,   9.62257539e-27],
           [  9.99885143e-01,   1.14856806e-04,   7.30324880e-25],
           [  9.99955163e-01,   4.48367166e-05,   8.82408733e-26],
           [  9.99961576e-01,   3.84240227e-05,   6.23837010e-26],
           [  9.99991524e-01,   8.47589867e-06,   2.09081186e-27],
           [  9.99981236e-01,   1.87640738e-05,   1.24661598e-26],
           [  9.99992874e-01,   7.12563295e-06,   1.41579845e-27],
           [  9.99987612e-01,   1.23883729e-05,   4.90488913e-27],
           [  9.92514386e-09,   9.99995068e-01,   4.92238946e-06],
           [  2.81161744e-09,   9.99976281e-01,   2.37163997e-05],
           [  1.58608201e-10,   9.99147203e-01,   8.52797328e-04],
           [  3.20936206e-09,   9.99979887e-01,   2.01102108e-05],
           [  1.41769171e-10,   9.99019410e-01,   9.80590261e-04],
           [  1.34843027e-09,   9.99940726e-01,   5.92727292e-05],
           [  1.48275804e-10,   9.99072649e-01,   9.27351189e-04],
           [  7.01402577e-05,   9.99929860e-01,   7.82466725e-11],
           [  7.98274948e-09,   9.99993534e-01,   6.45785196e-06],
           [  8.25410487e-09,   9.99993797e-01,   6.19426970e-06],
           [  1.63145958e-06,   9.99998360e-01,   8.50748157e-09],
           [  3.62438865e-09,   9.99982715e-01,   1.72812922e-05],
           [  7.10123000e-07,   9.99999266e-01,   2.39963651e-08],
           [  2.19376410e-10,   9.99430473e-01,   5.69526372e-04],
           [  4.40842296e-06,   9.99995589e-01,   2.46382864e-09],
           [  3.67207674e-08,   9.99999000e-01,   9.63527356e-07],
           [  1.42809879e-10,   9.99028291e-01,   9.71709222e-04],
           [  3.67635175e-06,   9.99996321e-01,   3.08979613e-09],
           [  5.15195942e-12,   9.45936370e-01,   5.40636300e-02],
           [  8.00753494e-07,   9.99999179e-01,   2.06592004e-08],
           [  4.41072836e-13,   5.93580187e-01,   4.06419813e-01],
           [  2.48716706e-07,   9.99999663e-01,   8.87474025e-08],
           [  1.11553496e-12,   7.70387256e-01,   2.29612744e-01],
           [  3.01218163e-09,   9.99978233e-01,   2.17643013e-05],
           [  6.74092428e-08,   9.99999481e-01,   4.51843906e-07],
           [  1.60820690e-08,   9.99997287e-01,   2.69695532e-06],
           [  2.50279695e-10,   9.99516668e-01,   4.83331455e-04],
           [  8.67286890e-13,   7.25443946e-01,   2.74556054e-01],
           [  1.94136395e-10,   9.99336870e-01,   6.63129541e-04],
           [  2.35046257e-04,   9.99764954e-01,   1.73213370e-11],
           [  8.31184015e-07,   9.99999149e-01,   1.97205855e-08],
           [  9.51617694e-06,   9.99990483e-01,   9.44062340e-10],
           [  8.23075824e-07,   9.99999157e-01,   1.99630652e-08],
           [  1.45909043e-14,   1.25902978e-01,   8.74097022e-01],
           [  9.15653663e-11,   9.98311607e-01,   1.68839247e-03],
           [  7.43966704e-10,   9.99875614e-01,   1.24385605e-04],
           [  5.52689872e-10,   9.99819854e-01,   1.80145500e-04],
           [  6.36834105e-10,   9.99849017e-01,   1.50982632e-04],
           [  1.11186266e-07,   9.99999647e-01,   2.42131810e-07],
           [  1.05800317e-08,   9.99995444e-01,   4.54549912e-06],
           [  3.09433480e-09,   9.99978951e-01,   2.10463547e-05],
           [  9.25529647e-10,   9.99905251e-01,   9.47481251e-05],
           [  1.92789944e-07,   9.99999685e-01,   1.21916057e-07],
           [  4.94115602e-05,   9.99950588e-01,   1.21101648e-10],
           [  7.81447411e-09,   9.99993361e-01,   6.63166922e-06],
           [  2.97695285e-07,   9.99999631e-01,   7.09305506e-08],
           [  3.24226072e-08,   9.99998842e-01,   1.12528516e-06],
           [  4.27392158e-08,   9.99999160e-01,   7.97427967e-07],
           [  4.59452664e-04,   9.99540547e-01,   7.50720002e-12],
           [  4.22858293e-08,   9.99999150e-01,   8.08100849e-07],
           [  2.70847094e-26,   4.13427816e-08,   9.99999959e-01],
           [  1.03345356e-18,   6.65624607e-04,   9.99334375e-01],
           [  2.37218813e-22,   6.36828511e-06,   9.99993632e-01],
           [  5.66073971e-19,   4.76658147e-04,   9.99523342e-01],
           [  1.31560301e-23,   1.27957104e-06,   9.99998720e-01],
           [  4.25521605e-25,   1.90616835e-07,   9.99999809e-01],
           [  1.11980477e-14,   1.09604382e-01,   8.90395618e-01],
           [  1.50074234e-21,   1.77246114e-05,   9.99982275e-01],
           [  3.45504953e-21,   2.81532268e-05,   9.99971847e-01],
           [  7.65161563e-25,   2.63976626e-07,   9.99999736e-01],
           [  1.89107898e-16,   1.19244800e-02,   9.88075520e-01],
           [  5.65090581e-19,   4.76198585e-04,   9.99523801e-01],
           [  1.44992009e-20,   6.23962870e-05,   9.99937604e-01],
           [  2.91038759e-20,   9.18475187e-05,   9.99908152e-01],
           [  1.32492366e-23,   1.28459344e-06,   9.99998715e-01],
           [  2.20083178e-21,   2.19201699e-05,   9.99978080e-01],
           [  1.52744732e-17,   2.96366398e-03,   9.97036336e-01],
           [  9.46967965e-24,   1.06618240e-06,   9.99998934e-01],
           [  1.59595014e-28,   2.39415393e-09,   9.99999998e-01],
           [  5.84505693e-15,   7.76200612e-02,   9.22379939e-01],
           [  7.99106985e-23,   3.48186224e-06,   9.99996518e-01],
           [  1.56590712e-18,   8.38185840e-04,   9.99161814e-01],
           [  3.34349936e-25,   1.66744938e-07,   9.99999833e-01],
           [  3.15474552e-15,   5.57056298e-02,   9.44294370e-01],
           [  1.12856928e-20,   5.42974161e-05,   9.99945703e-01],
           [  1.09282260e-18,   6.86572337e-04,   9.99313428e-01],
           [  2.96124617e-14,   1.81129636e-01,   8.18870364e-01],
           [  3.55492752e-14,   1.98548812e-01,   8.01451188e-01],
           [  1.78754800e-22,   5.44290923e-06,   9.99994557e-01],
           [  9.00937884e-16,   2.81480525e-02,   9.71851948e-01],
           [  1.01341406e-21,   1.42546802e-05,   9.99985745e-01],
           [  8.87413796e-20,   1.70497390e-04,   9.99829503e-01],
           [  1.95908602e-23,   1.59595718e-06,   9.99998404e-01],
           [  1.20569901e-12,   7.83523300e-01,   2.16476700e-01],
           [  1.03591996e-15,   3.03841422e-02,   9.69615858e-01],
           [  2.01777153e-24,   4.52107113e-07,   9.99999548e-01],
           [  2.27027959e-23,   1.73200324e-06,   9.99998268e-01],
           [  2.94263762e-17,   4.26181204e-03,   9.95738188e-01],
           [  1.03943413e-13,   3.32051564e-01,   6.67948436e-01],
           [  2.16147268e-19,   2.79403213e-04,   9.99720597e-01],
           [  7.19304204e-24,   9.15302655e-07,   9.99999085e-01],
           [  7.42616434e-20,   1.54451957e-04,   9.99845548e-01],
           [  1.03345356e-18,   6.65624607e-04,   9.99334375e-01],
           [  6.00800204e-24,   8.28288824e-07,   9.99999172e-01],
           [  1.43258291e-24,   3.73852067e-07,   9.99999626e-01],
           [  3.73190193e-21,   2.93834989e-05,   9.99970617e-01],
           [  4.11023391e-18,   1.43146740e-03,   9.98568533e-01],
           [  4.83922300e-18,   1.56711967e-03,   9.98432880e-01],
           [  1.83042506e-21,   1.97894410e-05,   9.99980211e-01],
           [  6.62613124e-16,   2.37833230e-02,   9.76216677e-01]])

```python
x = np.linspace(3.5, 8, 100)
y = np.linspace(1.5, 5, 100)
xs, ys = np.meshgrid(x, y)

Xt = np.vstack((xs.flat, ys.flat)).T
Xt = np.hstack((Xt, np.random.rand(*Xt.shape) * 0.001)) # fill random noise for other columns
classes, Y = clsf.use(Xt)

for k in range(3):
    zs = Y[:, k].reshape(xs.shape)

    plt.figure(figsize=(6,6))
    plt.imshow(zs, origin='lower', extent=(3,9,1,5))
    #plt.contourf(xs, ys, zs.reshape(xs.shape), alpha=0.3)
    plt.title("class: " + data.target_names[k])

    plt.scatter(data.data[data.target==k, 0], data.data[data.target==k, 1], marker='o')

```