{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matlab.engine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys \n",
    "sys.path.append('..')\n",
    "import utilities as utils \n",
    "import neural_nets.train as train \n",
    "import neural_nets.data_loaders as dl\n",
    "from relu_nets import ReLUNet\n",
    "import seaborn as sns\n",
    "sns.set()\n",
    "import matplotlib.pyplot as plt\n",
    "import experiment as exp\n",
    "import other_methods as om\n",
    "import numpy as np\n",
    "from lipMIP import LipProblem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_params = dl.RandomKParameters(num_points=256, k=20, radius=0.02, num_classes=2, dimension=2)\n",
    "dataset = dl.RandomDataset(data_params, batch_size=128, random_seed=420)\n",
    "trainset, _ = dataset.split_train_val(1.0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_params = train.TrainParameters(trainset, trainset, 1000, test_after_epoch=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 00 | Accuracy: 40.23\n",
      "Epoch 100 | Accuracy: 63.67\n",
      "Epoch 200 | Accuracy: 75.39\n",
      "Epoch 300 | Accuracy: 80.47\n",
      "Epoch 400 | Accuracy: 87.11\n",
      "Epoch 500 | Accuracy: 89.84\n",
      "Epoch 600 | Accuracy: 90.23\n",
      "Epoch 700 | Accuracy: 90.23\n",
      "Epoch 800 | Accuracy: 90.62\n",
      "Epoch 900 | Accuracy: 91.02\n"
     ]
    }
   ],
   "source": [
    "test_net = ReLUNet([2, 20, 40, 20, 2])\n",
    "train.training_loop(test_net, train_params )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'Randomly Generated Data Points')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 72992 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = dataset.plot_2d()\n",
    "ax.set_title('Randomly Generated Data Points')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'Neural Network Decision Boundaries')"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 70264 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = test_net.display_decision_bounds((0.0, 1.0), (0.0, 1.0), 100)\n",
    "ax = dataset.plot_2d(ax=ax)\n",
    "ax.set_title(\"Neural Network Decision Boundaries\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "methods = [om.LipLP, om.SeqLip, om.FastLip, om.LipSDP, om.CLEVER, LipProblem]\n",
    "exp1 = exp.Experiment(methods, network=test_net, c_vector=np.array([1.0, -1.0]), primal_norm='l1', verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MAXINT [<gurobi.Var *Awaiting Model Update*>, <gurobi.Var *Awaiting Model Update*>]\n",
      "MAXINT [<gurobi.Var *Awaiting Model Update*>, <gurobi.Var *Awaiting Model Update*>]\n",
      "Changed value of parameter Threads to 4\n",
      "   Prev: 0  Min: 0  Max: 1024  Default: 0\n",
      "Optimize a model with 717 rows, 401 columns and 4728 nonzeros\n",
      "Variable types: 331 continuous, 70 integer (70 binary)\n",
      "Coefficient statistics:\n",
      "  Matrix range     [4e-05, 1e+03]\n",
      "  Objective range  [1e+00, 1e+00]\n",
      "  Bounds range     [1e-06, 6e+02]\n",
      "  RHS range        [1e-06, 9e+02]\n",
      "Presolve removed 244 rows and 116 columns\n",
      "Presolve time: 0.03s\n",
      "Presolved: 473 rows, 285 columns, 3459 nonzeros\n",
      "Variable types: 221 continuous, 64 integer (64 binary)\n",
      "\n",
      "Root relaxation: objective 4.654979e+02, 137 iterations, 0.00 seconds\n",
      "\n",
      "    Nodes    |    Current Node    |     Objective Bounds      |     Work\n",
      " Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time\n",
      "\n",
      "     0     0  465.49787    0    5          -  465.49787      -     -    0s\n",
      "     0     0  459.23705    0   47          -  459.23705      -     -    0s\n",
      "     0     0  451.87246    0   52          -  451.87246      -     -    0s\n",
      "     0     0  451.86686    0   52          -  451.86686      -     -    0s\n",
      "     0     0  451.86683    0   52          -  451.86683      -     -    0s\n",
      "     0     0  451.38300    0   51          -  451.38300      -     -    0s\n",
      "     0     0  451.34715    0   51          -  451.34715      -     -    0s\n",
      "     0     0  451.33923    0   52          -  451.33923      -     -    0s\n",
      "     0     0  451.33893    0   52          -  451.33893      -     -    0s\n",
      "     0     0  450.92783    0   49          -  450.92783      -     -    0s\n",
      "     0     0  450.92007    0   49          -  450.92007      -     -    0s\n",
      "     0     0  450.91985    0   49          -  450.91985      -     -    0s\n",
      "     0     0  450.74494    0   51          -  450.74494      -     -    0s\n",
      "     0     0  450.73004    0   53          -  450.73004      -     -    0s\n",
      "     0     0  450.72924    0   52          -  450.72924      -     -    0s\n",
      "     0     0  450.71885    0   55          -  450.71885      -     -    0s\n",
      "H    0     0                      19.3009952  450.71885  2235%     -    0s\n",
      "     0     2  450.71885    0   55   19.30100  450.71885  2235%     -    0s\n",
      "*  133    50              28     105.2472581  230.46216   119%  35.2    0s\n",
      "*  196    40              39     118.6023633  230.46216  94.3%  30.3    0s\n",
      "*  347     3              36     131.9990623  153.86656  16.6%  24.5    0s\n",
      "*  395     0              35     153.5619972  153.78104  0.14%  22.7    0s\n",
      "\n",
      "Cutting planes:\n",
      "  Gomory: 4\n",
      "  Cover: 9\n",
      "  Implied bound: 10\n",
      "  Clique: 9\n",
      "  MIR: 96\n",
      "  Flow cover: 6\n",
      "  Inf proof: 1\n",
      "\n",
      "Explored 414 nodes (10615 simplex iterations) in 0.66 seconds\n",
      "Thread count was 4 (of 8 available processors)\n",
      "\n",
      "Solution count 5: 153.562 131.999 118.602 ... 19.301\n",
      "\n",
      "Optimal solution found (tolerance 1.00e-04)\n",
      "Best objective 1.535619972143e+02, best bound 1.535619972143e+02, gap 0.0000%\n"
     ]
    }
   ],
   "source": [
    "result =exp1.do_unit_hypercube_eval()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "def dim_scale(k, v, dim=2):\n",
    "    if k == 'SeqLip' or k == 'LipSDP':\n",
    "        return v * dim**0.5\n",
    "    else:\n",
    "        return v\n",
    "\n",
    "true_vals = [(k, dim_scale(k, v, 2)) for k, v in result.values().items()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('CLEVER', 153.56199645996094)\n",
      "('LipProblem', 153.56199721426526)\n",
      "('LipSDP', 573.8312241967099)\n",
      "('LipLP', 609.269775390625)\n",
      "('FastLip', 609.2698)\n",
      "('SeqLip', 661.1099590266736)\n"
     ]
    }
   ],
   "source": [
    "for el in sorted(true_vals, key=lambda d: d[1]):\n",
    "    print(el)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
