Master-Project/Notebooks/40_casadi_gaussiandome.ipynb
2021-07-30 16:21:14 +02:00

1887 lines
154 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import pickle"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import gpflow\n",
"import tensorflow as tf"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from gpflow.utilities import print_summary"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"import casadi"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load the existing GP model"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"ename": "FileNotFoundError",
"evalue": "[Errno 2] No such file or directory: 'gp_trainset.pkl'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-7-487b5e6e20b3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdf_sampled\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_pickle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"gp_trainset.pkl\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/usr/lib/python3.9/site-packages/pandas/io/pickle.py\u001b[0m in \u001b[0;36mread_pickle\u001b[0;34m(filepath_or_buffer, compression, storage_options)\u001b[0m\n\u001b[1;32m 183\u001b[0m \"\"\"\n\u001b[1;32m 184\u001b[0m \u001b[0mexcs_to_catch\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mAttributeError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mImportError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mModuleNotFoundError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 185\u001b[0;31m with get_handle(\n\u001b[0m\u001b[1;32m 186\u001b[0m \u001b[0mfilepath_or_buffer\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 187\u001b[0m \u001b[0;34m\"rb\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib/python3.9/site-packages/pandas/io/common.py\u001b[0m in \u001b[0;36mget_handle\u001b[0;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[0m\n\u001b[1;32m 649\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 650\u001b[0m \u001b[0;31m# Binary mode\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 651\u001b[0;31m \u001b[0mhandle\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mioargs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 652\u001b[0m \u001b[0mhandles\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 653\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'gp_trainset.pkl'"
]
}
],
"source": [
"df_sampled = pd.read_pickle(\"gp_trainset.pkl\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"x_scaler = pickle.load(open('x_scaler.pkl', 'rb'))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"df_input = df_sampled.drop(columns = ['y'])\n",
"df_output = df_sampled['y']"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"np_input = df_input.to_numpy()\n",
"np_output = df_output.to_numpy().reshape(-1, 1)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"np_input_sc = x_scaler.transform(np_input)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"n_states = np_input_sc.shape[1]"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"╒═════════════════════════════╤═══════════╤═════════════╤═════════╤═════════════╤═════════╤═════════╤════════════════╕\n",
"│ name │ class │ transform │ prior │ trainable │ shape │ dtype │ value │\n",
"╞═════════════════════════════╪═══════════╪═════════════╪═════════╪═════════════╪═════════╪═════════╪════════════════╡\n",
"│ Sum.kernels[0].variance │ Parameter │ Softplus │ │ True │ () │ float64 │ 1.0 │\n",
"├─────────────────────────────┼───────────┼─────────────┼─────────┼─────────────┼─────────┼─────────┼────────────────┤\n",
"│ Sum.kernels[0].lengthscales │ Parameter │ Softplus │ │ True │ (7,) │ float64 │ [1., 1., 1.... │\n",
"├─────────────────────────────┼───────────┼─────────────┼─────────┼─────────────┼─────────┼─────────┼────────────────┤\n",
"│ Sum.kernels[1].variance │ Parameter │ Softplus │ │ True │ () │ float64 │ 1.0 │\n",
"╘═════════════════════════════╧═══════════╧═════════════╧═════════╧═════════════╧═════════╧═════════╧════════════════╛\n"
]
}
],
"source": [
"k = gpflow.kernels.SquaredExponential(lengthscales=([1] * np_input.shape[1])) + gpflow.kernels.Constant()\n",
"print_summary(k)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"╒════════════════════════════════════╤═══════════╤══════════════════╤═════════╤═════════════╤═════════╤═════════╤════════════════╕\n",
"│ name │ class │ transform │ prior │ trainable │ shape │ dtype │ value │\n",
"╞════════════════════════════════════╪═══════════╪══════════════════╪═════════╪═════════════╪═════════╪═════════╪════════════════╡\n",
"│ GPR.kernel.kernels[0].variance │ Parameter │ Softplus │ │ True │ () │ float64 │ 1.0 │\n",
"├────────────────────────────────────┼───────────┼──────────────────┼─────────┼─────────────┼─────────┼─────────┼────────────────┤\n",
"│ GPR.kernel.kernels[0].lengthscales │ Parameter │ Softplus │ │ True │ (7,) │ float64 │ [1., 1., 1.... │\n",
"├────────────────────────────────────┼───────────┼──────────────────┼─────────┼─────────────┼─────────┼─────────┼────────────────┤\n",
"│ GPR.kernel.kernels[1].variance │ Parameter │ Softplus │ │ True │ () │ float64 │ 1.0 │\n",
"├────────────────────────────────────┼───────────┼──────────────────┼─────────┼─────────────┼─────────┼─────────┼────────────────┤\n",
"│ GPR.likelihood.variance │ Parameter │ Softplus + Shift │ │ True │ () │ float64 │ 1.0 │\n",
"╘════════════════════════════════════╧═══════════╧══════════════════╧═════════╧═════════════╧═════════╧═════════╧════════════════╛\n"
]
}
],
"source": [
"model = gpflow.models.GPR(\n",
" data = (np_input_sc, np_output), \n",
" kernel = k, \n",
" mean_function = None\n",
" )\n",
"print_summary(model)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"model_params_loaded = pickle.load(open(Path(Path.cwd(), 'gp_params.gpf'), 'rb'))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"gpflow.utilities.multiple_assign(model, model_params_loaded)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"## Load the test experimental data"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"def load_autoregressive_df(exp_id, lu = 1, ly = 3):\n",
" \n",
" df_wdb = pd.read_pickle(f\"../Data/Experimental_python/Exp{exp_id}_WDB.pkl\")\n",
" \n",
" df_carnot = pd.read_pickle(f\"../Data/CARNOT_output/Exp{exp_id}_full.pkl\")\n",
" df_data = df_carnot.loc[:, ['Power', 'Heat', 'Setpoint', 'OutsideTemp', 'SupplyTemp', 'InsideTemp', 'SolRad']]\n",
" df_simulated = df_carnot.loc[:, 'SimulatedTemp']\n",
"\n",
" df = pd.concat([df_wdb, df_data.reset_index(), df_simulated.reset_index()], axis = 1)\n",
"\n",
" df = df.loc[:,~df.columns.duplicated()]\n",
" \n",
" # Select the potentially useful columns\n",
" #df = df.loc[:, ['timestamp', 'zenith', 'azimuth', 'dni', 'dhi', 'OutsideTemp', 'Power', 'InsideTemp', 'SolRad', 'Setpoint']]\n",
" df = df.loc[:, ['timestamp','SolRad', 'OutsideTemp', 'Heat', 'InsideTemp']]\n",
"\n",
" df.drop(columns = ['timestamp'], inplace = True)\n",
" df.loc[:, 'timestamp'] = df_data.index\n",
" df.set_index('timestamp', drop = True, inplace = True)\n",
" \n",
" # Select the input/output and drop the columns that doesn't make to be used\n",
" dyn_in = 'Heat'\n",
" dyn_out = 'InsideTemp' \n",
" df.rename(columns = {dyn_in: 'u', dyn_out: 'y'}, inplace = True)\n",
"\n",
" # Add the regressive inputs/outputs\n",
" for idx in range(1, lu + 1):\n",
" df[f\"u_{idx}\"] = df['u'].shift(idx)\n",
" \n",
" for idx in range(1, ly + 1):\n",
" df[f\"y_{idx}\"] = df['y'].shift(idx)\n",
" \n",
" # Since some lines now have holes, drop them\n",
" df.dropna(inplace = True)\n",
" \n",
" return df"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"test_day = 5 # can be either 3 or 5 since \n",
"df_test = load_autoregressive_df(test_day)\n",
"np_test_in = df_test.drop(columns = ['y']).to_numpy()\n",
"np_test_in_sc = x_scaler.transform(np_test_in)\n",
"np_test_out = df_test['y'].to_numpy().reshape(-1, 1)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1440x360 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"## generate test points for prediction\n",
"xx = x_scaler.transform(np_test_in)\n",
"\n",
"## predict mean and variance of latent GP at test points\n",
"mean, var = model.predict_f(xx)\n",
"\n",
"## generate 10 samples from posterior\n",
"tf.random.set_seed(1) # for reproducibility\n",
"samples = model.predict_f_samples(xx, 10) # shape (10, 100, 1)\n",
"\n",
"## plot\n",
"plt.figure(figsize=(20, 5))\n",
"plt.title('Posterior sample functions')\n",
"plt.plot(df_test.index, mean, \"C0\", lw=2)\n",
"plt.fill_between(\n",
" df_test.index,\n",
" mean[:, 0] - 1.96 * np.sqrt(var[:, 0]),\n",
" mean[:, 0] + 1.96 * np.sqrt(var[:, 0]),\n",
" color=\"C0\",\n",
" alpha=0.2,\n",
")\n",
"#plt.plot(df_test.index, samples[:, :, 0].numpy().T, \"C0\", linewidth=0.5)\n",
"#plt.plot(df_test.index, np_test_out[:, :], ':', color = 'darkorange', lw = 2)\n",
"#_ = plt.ylim(21, 23.5)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"# Package the resulting regression model in a CasADi callback\n",
"class GPR(casadi.Callback):\n",
" def __init__(self, name, opts={}):\n",
" casadi.Callback.__init__(self)\n",
" self.construct(name, opts)\n",
" \n",
" # Number of inputs and outputs\n",
" def get_n_in(self): return 1\n",
" def get_n_out(self): return 1\n",
"\n",
" def get_sparsity_in(self,i):\n",
" return casadi.Sparsity.dense(n_states,1)\n",
"\n",
" def eval(self, arg):\n",
" x_scaled = x_scaler.transform(np.array(arg[0]).reshape(1, -1))\n",
" [mean, _] = model.predict_y(x_scaled)\n",
" return [mean.numpy()]"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"GPR:(i0[7])->(o0) CallbackInternal\n"
]
}
],
"source": [
"# Instantiate the Callback (make sure to keep a reference to it!)\n",
"gpr = GPR('GPR', {\"enable_fd\":True})\n",
"print(gpr)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"## CasADi optimization problem"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"T_set = 20\n",
"N_horizon = 10"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test area"
]
},
{
"cell_type": "code",
"execution_count": 126,
"metadata": {},
"outputs": [],
"source": [
"X = casadi.MX.sym(\"X\", N_horizon, n_states)\n",
"W = casadi.MX.sym(\"W\", N_horizon, 2)\n",
"x0_lags = casadi.MX.sym(\"lags\", 1, n_states - 3)"
]
},
{
"cell_type": "code",
"execution_count": 127,
"metadata": {},
"outputs": [],
"source": [
"# Impose initial lags"
]
},
{
"cell_type": "code",
"execution_count": 128,
"metadata": {},
"outputs": [],
"source": [
"g = casadi.vec(X[0,3:] - x0_lags)"
]
},
{
"cell_type": "code",
"execution_count": 129,
"metadata": {},
"outputs": [],
"source": [
"# Impose disturbances"
]
},
{
"cell_type": "code",
"execution_count": 130,
"metadata": {},
"outputs": [],
"source": [
"g = casadi.vertcat(\n",
" g,\n",
" casadi.vec(X[:, :2] - W)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 131,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(24, 1)"
]
},
"execution_count": 131,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g.shape"
]
},
{
"cell_type": "code",
"execution_count": 132,
"metadata": {},
"outputs": [],
"source": [
"# Calculate objective\n",
"J = 0\n",
"for idx in range(N_horizon):\n",
" J += casadi.norm_2(gpr(X[0,:]) - T_set)"
]
},
{
"cell_type": "code",
"execution_count": 133,
"metadata": {},
"outputs": [],
"source": [
"# Impose lags\n",
"for idx in range(1, N_horizon):\n",
" g = casadi.vertcat(\n",
" g,\n",
" X[idx, 3] - X[idx-1, 2],\n",
" X[idx, 4] - gpr(X[idx-1,:]),\n",
" X[idx, 5] - X[idx-1, 4],\n",
" X[idx, 6] - X[idx-1, 5]\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 134,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(60, 1)"
]
},
"execution_count": 134,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g.shape"
]
},
{
"cell_type": "code",
"execution_count": 135,
"metadata": {},
"outputs": [],
"source": [
"# Impose input inequality constraints"
]
},
{
"cell_type": "code",
"execution_count": 136,
"metadata": {},
"outputs": [],
"source": [
"g = casadi.vertcat(\n",
" g,\n",
" X[:, 2]\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 137,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(70, 1)"
]
},
"execution_count": 137,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g.shape"
]
},
{
"cell_type": "code",
"execution_count": 138,
"metadata": {},
"outputs": [],
"source": [
"J = casadi.norm_2(gpr(X.reshape((N_horizon, -1)).T) - 25)"
]
},
{
"cell_type": "code",
"execution_count": 139,
"metadata": {},
"outputs": [],
"source": [
"# Define parameters\n",
"p = casadi.vertcat(\n",
" casadi.vec(W),\n",
" casadi.vec(x0_lags)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 140,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(70, 1)"
]
},
"execution_count": 140,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"g.shape"
]
},
{
"cell_type": "code",
"execution_count": 141,
"metadata": {},
"outputs": [],
"source": [
"prob = {\"x\": casadi.vec(X), \"f\": J, \"p\": p, \"g\": g}\n",
"options = {\"ipopt\": {\"hessian_approximation\": \"limited-memory\", \"max_iter\": 100, \n",
" \"acceptable_tol\": 1e-8, \"acceptable_obj_change_tol\": 1e-6}}"
]
},
{
"cell_type": "code",
"execution_count": 142,
"metadata": {},
"outputs": [],
"source": [
"solver = casadi.nlpsol(\"solver\",\"ipopt\",prob, options)"
]
},
{
"cell_type": "code",
"execution_count": 143,
"metadata": {},
"outputs": [],
"source": [
"real_W = casadi.DM(N_horizon, 2)\n",
"real_W[:, :] = 2 * np.ones((N_horizon, 2))"
]
},
{
"cell_type": "code",
"execution_count": 144,
"metadata": {},
"outputs": [],
"source": [
"real_x0 = casadi.DM(1, 4)\n",
"real_x0[:] = [1, 2, 3, 4]"
]
},
{
"cell_type": "code",
"execution_count": 145,
"metadata": {},
"outputs": [],
"source": [
"real_p = casadi.vertcat(\n",
" casadi.vec(real_W),\n",
" casadi.vec(real_x0)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 146,
"metadata": {},
"outputs": [],
"source": [
"Pel_max = 6300\n",
"COP_heat = 1\n",
"COP_cool = 3\n",
"u_min = - COP_cool * Pel_max\n",
"u_max = COP_heat * Pel_max"
]
},
{
"cell_type": "code",
"execution_count": 147,
"metadata": {},
"outputs": [],
"source": [
"real_lbg = [0] * (4 + 2 * N_horizon + 4 * (N_horizon - 1)) + [u_min] * (N_horizon)\n",
"real_ubg = [0] * (4 + 2 * N_horizon + 4 * (N_horizon - 1)) + [u_max] * (N_horizon)"
]
},
{
"cell_type": "code",
"execution_count": 148,
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is Ipopt version 3.13.4, running with linear solver mumps.\n",
"NOTE: Other linear solvers might be more efficient (see Ipopt documentation).\n",
"\n",
"Number of nonzeros in equality constraint Jacobian...: 150\n",
"Number of nonzeros in inequality constraint Jacobian.: 10\n",
"Number of nonzeros in Lagrangian Hessian.............: 0\n",
"\n",
"Total number of variables............................: 70\n",
" variables with only lower bounds: 0\n",
" variables with lower and upper bounds: 0\n",
" variables with only upper bounds: 0\n",
"Total number of equality constraints.................: 60\n",
"Total number of inequality constraints...............: 10\n",
" inequality constraints with only lower bounds: 0\n",
" inequality constraints with lower and upper bounds: 10\n",
" inequality constraints with only upper bounds: 0\n",
"\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 0 3.9449223e+01 1.25e+01 2.64e-06 0.0 0.00e+00 - 0.00e+00 0.00e+00 0\n",
" 1 3.3511925e+01 3.72e+00 1.33e+01 -1.9 1.29e+01 - 9.90e-01 1.00e+00h 1\n",
" 2 2.5550836e+01 1.57e+00 6.16e+00 -3.9 7.70e+00 - 9.90e-01 1.00e+00f 1\n",
" 3 2.1201222e+01 4.21e-01 9.27e-01 -2.0 4.10e+00 - 9.95e-01 1.00e+00f 1\n",
" 4 2.0447497e+01 2.04e-02 2.12e-02 -3.7 1.32e+00 - 1.00e+00 1.00e+00h 1\n",
" 5 2.0438965e+01 4.40e-06 1.84e-03 -5.6 2.75e-02 - 1.00e+00 1.00e+00h 1\n",
" 6 2.0438967e+01 5.11e-07 2.62e-03 -7.7 3.37e-03 - 1.00e+00 1.00e+00h 1\n",
" 7 2.0438968e+01 6.53e-07 2.75e-03 -9.7 1.88e-03 - 1.00e+00 1.00e+00h 1\n",
" 8 2.0438963e+01 3.90e-06 3.95e-03 -11.0 1.08e-02 - 1.00e+00 1.00e+00h 1\n",
" 9 2.0438961e+01 5.29e-06 3.22e-03 -11.0 2.22e-02 - 1.00e+00 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 10 2.0438886e+01 3.04e-05 4.20e-03 -11.0 2.51e-01 - 1.00e+00 1.00e+00h 1\n",
" 11 2.0438836e+01 9.78e-05 1.52e-03 -11.0 1.29e-01 - 1.00e+00 1.00e+00h 1\n",
" 12 2.0438696e+01 1.58e-04 1.78e-03 -11.0 6.98e-01 - 1.00e+00 1.00e+00h 1\n",
" 13 2.0438535e+01 1.60e-04 2.71e-03 -11.0 2.01e+00 - 1.00e+00 1.00e+00h 1\n",
" 14 2.0437940e+01 1.57e-03 2.03e-03 -11.0 6.07e+00 - 1.00e+00 1.00e+00h 1\n",
" 15 2.0101748e+01 5.47e-01 1.42e-02 -11.0 1.89e+03 - 1.00e+00 1.00e+00f 1\n",
" 16 2.0225509e+01 8.02e-02 3.42e-03 -11.0 1.15e+03 - 1.00e+00 1.00e+00h 1\n",
" 17 1.9052743e+01 1.15e+00 4.36e-02 -9.0 4.15e+06 - 2.95e-03 1.68e-03f 1\n",
" 18 1.9031763e+01 1.16e+00 4.43e-02 -9.0 1.59e+07 - 1.57e-03 4.38e-06f 1\n",
" 19 1.9043861e+01 1.14e+00 4.39e-02 -8.8 2.48e+02 - 1.00e+00 9.85e-03h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 20 1.9043866e+01 1.14e+00 4.37e-02 -6.8 2.36e+03 - 1.00e+00 7.97e-06h 1\n",
" 21 2.0452454e+01 5.04e-02 5.05e-02 -4.8 1.61e+01 - 5.26e-01 1.00e+00h 1\n",
" 22 2.0451237e+01 5.01e-02 5.00e-02 -5.2 6.60e+00 - 1.00e+00 7.17e-03h 1\n",
" 23 2.0287931e+01 7.14e-04 3.33e-03 -5.2 5.33e-01 - 1.00e+00 1.00e+00h 1\n",
" 24 2.0286733e+01 2.95e-04 2.01e-03 -7.3 1.86e+00 - 1.00e+00 1.00e+00h 1\n",
" 25 2.0285017e+01 1.15e-03 2.71e-03 -5.2 1.01e+01 - 4.53e-01 1.00e+00h 1\n",
" 26 2.0286965e+01 1.20e-06 2.97e-03 -5.4 6.28e+00 - 1.00e+00 1.00e+00H 1\n",
" 27 2.0285508e+01 1.01e-03 2.92e-03 -4.9 1.32e+01 - 4.31e-01 1.00e+00h 1\n",
" 28 2.0274275e+01 7.04e-03 2.70e-03 -5.2 6.66e+01 - 1.00e+00 7.69e-01h 1\n",
" 29 1.9690313e+01 3.37e-01 2.08e-02 -6.2 2.04e+03 - 8.98e-01 1.00e+00f 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 30 2.0318305e+01 7.03e-03 1.52e-02 -6.1 5.81e+03 - 1.00e+00 1.00e+00H 1\n",
" 31 1.9205720e+01 2.71e+00 1.38e-01 -5.5 5.63e+03 - 1.00e+00 1.00e+00f 1\n",
" 32 1.8965587e+01 3.01e+00 2.09e-01 -5.5 3.85e+05 - 6.00e-02 3.88e-03f 1\n",
" 33 2.0007446e+01 3.52e-01 8.72e-02 -4.9 2.53e+03 - 1.38e-04 9.46e-01h 1\n",
" 34 2.0005216e+01 3.52e-01 8.73e-02 -5.7 1.38e+04 - 3.27e-01 6.33e-04h 1\n",
" 35 1.9839644e+01 3.61e-01 8.11e-02 -5.7 3.11e+04 - 7.04e-01 1.58e-02f 1\n",
" 36 1.9864314e+01 1.62e-01 3.76e-02 -5.7 2.40e+03 - 1.00e+00 1.00e+00h 1\n",
" 37 1.9612312e+01 2.34e-01 3.55e-02 -4.0 3.43e+05 - 5.91e-01 9.23e-03f 1\n",
" 38 1.9590066e+01 5.17e-01 3.90e-02 -2.7 6.88e+03 - 1.00e+00 1.72e-01f 1\n",
" 39 1.9546835e+01 4.65e-01 1.11e-01 -8.4 6.34e+03 - 8.51e-02 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 40 1.8280307e+01 2.18e+00 8.69e-02 -8.7 2.48e+04 - 2.06e-03 1.59e-01f 1\n",
" 41 1.8082053e+01 1.53e+00 1.51e-01 -1.4 8.12e+03 - 3.73e-01 5.90e-01F 1\n",
" 42 1.7931981e+01 2.09e+00 1.27e-01 -1.3 7.40e+03 - 5.71e-01 1.00e+00f 1\n",
" 43 1.9324711e+01 6.94e-01 1.81e-01 -1.0 2.91e+03 - 1.00e+00 6.90e-01h 1\n",
" 44 1.8679710e+01 2.27e+00 5.63e-02 -7.0 4.42e+03 - 5.07e-01 1.00e+00f 1\n",
" 45 1.9232277e+01 1.20e+00 7.07e-02 -7.4 3.47e+03 - 3.19e-01 1.00e+00h 1\n",
" 46 1.8612852e+01 3.80e+00 1.36e-01 -7.6 1.00e+04 - 6.55e-02 8.21e-01f 1\n",
" 47 1.9108327e+01 2.07e+00 1.62e-01 -1.7 1.67e+04 - 3.98e-01 5.85e-01H 1\n",
" 48 1.8380263e+01 2.73e+00 3.06e-01 -1.7 2.36e+04 - 4.98e-01 6.34e-01F 1\n",
" 49 1.9683542e+01 6.11e-01 4.46e-01 -1.7 6.70e+03 - 8.19e-01 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 50 1.9018329e+01 6.53e-01 1.95e-01 -1.7 2.90e+03 - 1.00e+00 1.00e+00h 1\n",
" 51 1.7469656e+01 1.84e+00 1.16e-01 -1.8 1.60e+04 - 6.47e-02 6.45e-01f 1\n",
" 52 1.8482093e+01 2.90e+00 1.23e-01 -2.8 1.33e+04 - 2.29e-01 5.98e-01H 1\n",
" 53 1.7603679e+01 5.75e+00 2.29e-01 -2.0 8.75e+03 - 2.90e-01 9.70e-01f 1\n",
" 54 1.7585994e+01 1.72e+00 1.57e-01 -2.0 6.19e+03 - 5.76e-01 6.81e-01h 1\n",
" 55 1.7858398e+01 1.37e+00 1.03e-01 -2.0 6.67e+03 - 6.90e-02 3.97e-01h 1\n",
" 56 1.8787279e+01 5.29e-01 7.68e-02 -2.0 2.27e+03 - 1.42e-01 7.27e-01h 1\n",
" 57 2.0165113e+01 3.50e-01 1.35e-01 -2.5 4.78e+03 - 8.58e-01 1.00e+00h 1\n",
" 58 1.8138493e+01 2.72e+00 1.44e-01 -2.4 1.87e+04 - 2.45e-01 4.87e-01f 1\n",
" 59 1.7475863e+01 2.54e+00 2.43e-01 -2.4 2.31e+04 - 6.37e-01 2.28e-01f 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 60 1.7812201e+01 1.83e+00 5.38e-02 -2.4 1.47e+04 - 6.84e-01 3.50e-01h 1\n",
" 61 1.7715436e+01 1.15e+00 2.43e-02 -2.0 9.12e+03 - 3.37e-01 3.25e-01f 1\n",
" 62 1.8762738e+01 1.06e+00 2.15e-02 -2.3 1.75e+03 - 1.00e+00 1.00e+00h 1\n",
" 63 1.6718129e+01 2.24e+00 1.16e-01 -4.1 8.00e+03 - 3.55e-01 9.29e-01f 1\n",
" 64 1.6720305e+01 2.09e+00 9.80e-02 -1.9 8.78e+03 - 3.14e-01 6.25e-02h 5\n",
" 65 1.6721588e+01 2.05e+00 9.38e-02 -2.3 2.17e+04 - 4.44e-02 2.22e-02h 4\n",
" 66 1.6818979e+01 1.88e+00 7.00e-02 -2.3 1.78e+04 - 7.86e-02 7.86e-02s 19\n",
" 67 1.7735738e+01 1.35e+00 1.24e-01 -2.3 1.49e+04 - 2.78e-01 0.00e+00S 19\n",
" 68 1.7941257e+01 1.09e+00 1.19e-01 -2.3 2.18e+03 - 7.08e-01 1.95e-01h 1\n",
" 69 1.8053920e+01 1.01e+00 9.38e-02 -1.0 2.41e+04 - 3.84e-01 8.04e-02f 2\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 70 1.8020243e+01 9.45e-01 8.23e-02 -1.6 1.67e+04 - 6.33e-01 5.86e-02h 2\n",
" 71 1.7990070e+01 8.02e-01 5.45e-02 -1.6 4.67e+03 - 1.00e+00 1.73e-01h 2\n",
" 72 2.0935687e+01 1.97e-01 4.10e+00 -1.6 4.22e+00 - 1.00e+00 1.00e+00h 1\n",
" 73 2.0661433e+01 2.19e-03 5.07e-01 -1.6 5.24e-01 - 1.00e+00 1.00e+00h 1\n",
" 74 2.0660515e+01 1.52e-06 2.08e-03 -1.6 6.98e-03 - 1.00e+00 1.00e+00h 1\n",
" 75 2.0660515e+01 5.74e-06 1.81e-03 -2.3 9.32e-03 - 1.00e+00 1.00e+00h 1\n",
" 76 2.0660517e+01 4.03e-06 3.60e-03 -3.5 7.10e-03 - 1.00e+00 1.00e+00h 1\n",
" 77 2.0660508e+01 7.67e-06 3.65e-03 -3.5 3.08e-02 - 1.00e+00 1.00e+00h 1\n",
" 78 2.0660450e+01 2.75e-05 3.40e-03 -3.5 1.31e-01 - 1.00e+00 1.00e+00h 1\n",
" 79 2.0660503e+01 8.16e-06 1.70e-03 -3.5 5.61e-02 - 1.00e+00 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 80 2.0660511e+01 8.66e-06 1.97e-03 -5.2 2.96e-02 - 1.00e+00 1.00e+00h 1\n",
" 81 2.0660522e+01 1.57e-08 1.33e-04 -5.2 5.84e-02 - 1.00e+00 1.00e+00H 1\n",
" 82 2.0660492e+01 2.04e-05 1.45e-03 -11.0 6.37e-02 - 1.00e+00 1.00e+00h 1\n",
" 83 2.0660520e+01 1.57e-08 6.42e-05 -9.2 5.61e-02 - 1.00e+00 1.00e+00H 1\n",
" 84 2.0660185e+01 3.55e-04 2.36e-03 -11.0 1.56e+00 - 1.00e+00 1.00e+00f 1\n",
" 85 2.0658603e+01 8.13e-04 8.12e-03 -11.0 3.39e+00 - 1.00e+00 1.00e+00h 1\n",
" 86 2.0657043e+01 3.57e-03 2.50e-03 -11.0 4.09e+00 - 1.00e+00 1.00e+00h 1\n",
" 87 2.0659602e+01 8.15e-04 2.44e-03 -11.0 2.39e+00 - 1.00e+00 1.00e+00h 1\n",
" 88 2.0661096e+01 4.14e-06 3.07e-03 -11.0 1.63e+01 - 1.00e+00 1.00e+00H 1\n",
" 89 2.0620802e+01 5.53e-02 3.42e-03 -11.0 4.33e+02 - 1.00e+00 5.37e-01f 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 90 2.0142987e+01 8.07e-01 2.32e-02 -11.0 1.40e+04 - 2.28e-02 2.55e-01f 1\n",
" 91 2.0130613e+01 7.91e-01 2.24e-02 -11.0 1.20e+04 - 3.59e-09 2.23e-02h 1\n",
" 92 2.0390038e+01 3.94e-01 1.90e-03 -11.0 2.52e+02 - 1.00e+00 5.00e-01h 2\n",
" 93 1.9729689e+01 2.63e+00 1.58e-01 -11.0 2.82e+04 - 5.08e-03 1.16e-01f 1\n",
" 94 1.9587992e+01 1.79e+00 8.44e-02 -11.0 2.08e+03 - 5.77e-10 3.06e-01h 1\n",
" 95 1.9832003e+01 4.27e-01 6.73e-02 -11.0 2.24e+03 - 7.10e-01 8.61e-01h 1\n",
" 96 1.9832003e+01 4.27e-01 6.73e-02 -11.0 1.97e+03 - 3.83e-09 3.83e-09s 2\n",
" 97 1.9832003e+01 4.27e-01 6.73e-02 -11.0 1.05e+03 - 1.38e-10 1.38e-10s 2\n",
" 98r 1.9832003e+01 4.27e-01 9.99e+02 -0.4 0.00e+00 - 0.00e+00 0.00e+00R 1\n",
" 99r 1.9998665e+01 3.43e-01 8.99e+02 -6.4 1.76e+02 - 9.90e-01 1.96e-03f 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 100 2.0574084e+01 7.10e-02 5.51e-02 -11.0 9.13e+02 - 7.53e-02 1.00e+00H 1\n",
"\n",
"Number of Iterations....: 100\n",
"\n",
" (scaled) (unscaled)\n",
"Objective...............: 2.0574083887724495e+01 2.0574083887724495e+01\n",
"Dual infeasibility......: 5.5068470105394229e-02 5.5068470105394229e-02\n",
"Constraint violation....: 7.0957538043959545e-02 7.0957538043959545e-02\n",
"Complementarity.........: 9.2513374353537508e-05 9.2513374353537508e-05\n",
"Overall NLP error.......: 7.0957538043959545e-02 7.0957538043959545e-02\n",
"\n",
"\n",
"Number of objective function evaluations = 153\n",
"Number of objective gradient evaluations = 101\n",
"Number of equality constraint evaluations = 153\n",
"Number of inequality constraint evaluations = 153\n",
"Number of equality constraint Jacobian evaluations = 102\n",
"Number of inequality constraint Jacobian evaluations = 102\n",
"Number of Lagrangian Hessian evaluations = 0\n",
"Total CPU secs in IPOPT (w/o function evaluations) = 8.870\n",
"Total CPU secs in NLP function evaluations = 918.825\n",
"\n",
"EXIT: Maximum Number of Iterations Exceeded.\n",
" solver : t_proc (avg) t_wall (avg) n_eval\n",
" nlp_f | 26.14 s (170.84ms) 20.41 s (133.39ms) 153\n",
" nlp_g | 23.14 s (151.26ms) 17.96 s (117.37ms) 153\n",
" nlp_grad | 9.73 s ( 9.73 s) 7.60 s ( 7.60 s) 1\n",
" nlp_grad_f | 514.07 s ( 5.04 s) 398.13 s ( 3.90 s) 102\n",
" nlp_jac_g | 451.34 s ( 4.38 s) 348.97 s ( 3.39 s) 103\n",
" total | 1.02ks ( 1.02ks) 793.27 s (793.27 s) 1\n"
]
},
{
"data": {
"text/plain": [
"DM([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -5276.26, -10771, 4088.54, -4909.72, 5339.09, 6299.99, 6299.8, -14154.4, 4279.15, 599.066, 1, -5276.26, -10771, 4088.54, -4909.72, 5339.09, 6299.99, 6299.8, -14154.4, 4279.15, 2, 12.1019, 16.044, 18.912, 20.1879, 20.6361, 20.8219, 20.8302, 20.7725, 20.3594, 3, 2, 12.1019, 16.044, 18.912, 20.1879, 20.6361, 20.8219, 20.8302, 20.7725, 4, 3, 2, 12.1019, 16.044, 18.912, 20.1879, 20.6361, 20.8219, 20.8302])"
]
},
"execution_count": 148,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res = solver(p = real_p, lbg = real_lbg, ubg = real_ubg)\n",
"res['x']"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DM([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3.03502e+07, -2.52271e+07, 2.05064e+07, -4.67068e+07, 9.09586e+07, 3.50245e+07, -1.16515e+08, 1.398e+08, -8.8153e+07, 5.69382e+06, 1, 3.03502e+07, -2.52271e+07, 2.05064e+07, -4.67068e+07, 9.09586e+07, 3.50245e+07, -1.16515e+08, 1.398e+08, -8.8153e+07, 2, 16.4965, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 3, 2, 16.4965, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 4, 3, 2, 16.4965, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653])"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res['x']"
]
},
{
"cell_type": "code",
"execution_count": 149,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DM(\n",
"[[2, 2, -5276.26, 1, 2, 3, 4], \n",
" [2, 2, -10771, -5276.26, 12.1019, 2, 3], \n",
" [2, 2, 4088.54, -10771, 16.044, 12.1019, 2], \n",
" [2, 2, -4909.72, 4088.54, 18.912, 16.044, 12.1019], \n",
" [2, 2, 5339.09, -4909.72, 20.1879, 18.912, 16.044], \n",
" [2, 2, 6299.99, 5339.09, 20.6361, 20.1879, 18.912], \n",
" [2, 2, 6299.8, 6299.99, 20.8219, 20.6361, 20.1879], \n",
" [2, 2, -14154.4, 6299.8, 20.8302, 20.8219, 20.6361], \n",
" [2, 2, 4279.15, -14154.4, 20.7725, 20.8302, 20.8219], \n",
" [2, 2, 599.066, 4279.15, 20.3594, 20.7725, 20.8302]])"
]
},
"execution_count": 149,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res['x'].reshape((N_horizon, -1))"
]
},
{
"cell_type": "code",
"execution_count": 150,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DM([[12.1019, 16.041, 18.9237, 20.1169, 20.637, 20.8187, 20.8361, 20.7795, 20.3782, 20.2176]])"
]
},
"execution_count": 150,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"gpr(res['x'].reshape((N_horizon, -1)).T)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DM([[16.4965, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653, 20.1653]])"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"gpr(res['x'].reshape((N_horizon, -1)).T)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"# Solve the optimization problem for one time step on real data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def load_autoregressive_df(exp_id, lu = 1, ly = 3):\n",
" \n",
" df_wdb = pd.read_pickle(f\"../Data/Experimental_python/Exp{exp_id}_WDB.pkl\")\n",
" \n",
" df_carnot = pd.read_pickle(f\"../Data/CARNOT_output/Exp{exp_id}_full.pkl\")\n",
" df_data = df_carnot.loc[:, ['Power', 'Heat', 'Setpoint', 'OutsideTemp', 'SupplyTemp', 'InsideTemp', 'SolRad']]\n",
" df_simulated = df_carnot.loc[:, 'SimulatedTemp']\n",
"\n",
" df = pd.concat([df_wdb, df_data.reset_index(), df_simulated.reset_index()], axis = 1)\n",
"\n",
" df = df.loc[:,~df.columns.duplicated()]\n",
" \n",
" # Select the potentially useful columns\n",
" #df = df.loc[:, ['timestamp', 'zenith', 'azimuth', 'dni', 'dhi', 'OutsideTemp', 'Power', 'InsideTemp', 'SolRad', 'Setpoint']]\n",
" df = df.loc[:, ['timestamp','SolRad', 'OutsideTemp', 'Heat', 'InsideTemp']]\n",
"\n",
" df.drop(columns = ['timestamp'], inplace = True)\n",
" df.loc[:, 'timestamp'] = df_data.index\n",
" df.set_index('timestamp', drop = True, inplace = True)\n",
" \n",
" # Select the input/output and drop the columns that doesn't make to be used\n",
" dyn_in = 'Heat'\n",
" dyn_out = 'InsideTemp' \n",
" df.rename(columns = {dyn_in: 'u', dyn_out: 'y'}, inplace = True)\n",
"\n",
" # Add the regressive inputs/outputs\n",
" for idx in range(1, lu + 1):\n",
" df[f\"u_{idx}\"] = df['u'].shift(idx)\n",
" \n",
" for idx in range(1, ly + 1):\n",
" df[f\"y_{idx}\"] = df['y'].shift(idx)\n",
" \n",
" # Since some lines now have holes, drop them\n",
" df.dropna(inplace = True)\n",
" \n",
" return df"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>SolRad</th>\n",
" <th>OutsideTemp</th>\n",
" <th>u</th>\n",
" <th>y</th>\n",
" <th>u_1</th>\n",
" <th>y_1</th>\n",
" <th>y_2</th>\n",
" <th>y_3</th>\n",
" </tr>\n",
" <tr>\n",
" <th>timestamp</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2017-06-16 20:15:00+02:00</th>\n",
" <td>104.558300</td>\n",
" <td>23.0</td>\n",
" <td>-12088.862069</td>\n",
" <td>22.883333</td>\n",
" <td>-12927.931034</td>\n",
" <td>23.066667</td>\n",
" <td>23.283333</td>\n",
" <td>23.166667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-16 20:20:00+02:00</th>\n",
" <td>99.697333</td>\n",
" <td>23.0</td>\n",
" <td>-20.300000</td>\n",
" <td>22.666667</td>\n",
" <td>-12088.862069</td>\n",
" <td>22.883333</td>\n",
" <td>23.066667</td>\n",
" <td>23.283333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-16 20:25:00+02:00</th>\n",
" <td>87.216800</td>\n",
" <td>23.0</td>\n",
" <td>-33.517241</td>\n",
" <td>22.650000</td>\n",
" <td>-20.300000</td>\n",
" <td>22.666667</td>\n",
" <td>22.883333</td>\n",
" <td>23.066667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-16 20:30:00+02:00</th>\n",
" <td>85.049400</td>\n",
" <td>23.0</td>\n",
" <td>-33.620690</td>\n",
" <td>22.800000</td>\n",
" <td>-33.517241</td>\n",
" <td>22.650000</td>\n",
" <td>22.666667</td>\n",
" <td>22.883333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-16 20:35:00+02:00</th>\n",
" <td>77.971900</td>\n",
" <td>23.0</td>\n",
" <td>-40.241379</td>\n",
" <td>22.933333</td>\n",
" <td>-33.620690</td>\n",
" <td>22.800000</td>\n",
" <td>22.650000</td>\n",
" <td>22.666667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-19 05:35:00+02:00</th>\n",
" <td>6.040567</td>\n",
" <td>18.0</td>\n",
" <td>-2.896552</td>\n",
" <td>22.300000</td>\n",
" <td>-3.000000</td>\n",
" <td>22.300000</td>\n",
" <td>22.316667</td>\n",
" <td>22.316667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-19 05:40:00+02:00</th>\n",
" <td>7.556467</td>\n",
" <td>18.0</td>\n",
" <td>-3.433333</td>\n",
" <td>22.266667</td>\n",
" <td>-2.896552</td>\n",
" <td>22.300000</td>\n",
" <td>22.300000</td>\n",
" <td>22.316667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-19 05:45:00+02:00</th>\n",
" <td>9.632667</td>\n",
" <td>18.0</td>\n",
" <td>-5.448276</td>\n",
" <td>22.116667</td>\n",
" <td>-3.433333</td>\n",
" <td>22.266667</td>\n",
" <td>22.300000</td>\n",
" <td>22.300000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-19 05:50:00+02:00</th>\n",
" <td>11.941100</td>\n",
" <td>18.0</td>\n",
" <td>-3.241379</td>\n",
" <td>22.233333</td>\n",
" <td>-5.448276</td>\n",
" <td>22.116667</td>\n",
" <td>22.266667</td>\n",
" <td>22.300000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-19 05:55:00+02:00</th>\n",
" <td>14.208433</td>\n",
" <td>18.0</td>\n",
" <td>-4.233333</td>\n",
" <td>22.150000</td>\n",
" <td>-3.241379</td>\n",
" <td>22.233333</td>\n",
" <td>22.116667</td>\n",
" <td>22.266667</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>693 rows × 8 columns</p>\n",
"</div>"
],
"text/plain": [
" SolRad OutsideTemp u y \\\n",
"timestamp \n",
"2017-06-16 20:15:00+02:00 104.558300 23.0 -12088.862069 22.883333 \n",
"2017-06-16 20:20:00+02:00 99.697333 23.0 -20.300000 22.666667 \n",
"2017-06-16 20:25:00+02:00 87.216800 23.0 -33.517241 22.650000 \n",
"2017-06-16 20:30:00+02:00 85.049400 23.0 -33.620690 22.800000 \n",
"2017-06-16 20:35:00+02:00 77.971900 23.0 -40.241379 22.933333 \n",
"... ... ... ... ... \n",
"2017-06-19 05:35:00+02:00 6.040567 18.0 -2.896552 22.300000 \n",
"2017-06-19 05:40:00+02:00 7.556467 18.0 -3.433333 22.266667 \n",
"2017-06-19 05:45:00+02:00 9.632667 18.0 -5.448276 22.116667 \n",
"2017-06-19 05:50:00+02:00 11.941100 18.0 -3.241379 22.233333 \n",
"2017-06-19 05:55:00+02:00 14.208433 18.0 -4.233333 22.150000 \n",
"\n",
" u_1 y_1 y_2 y_3 \n",
"timestamp \n",
"2017-06-16 20:15:00+02:00 -12927.931034 23.066667 23.283333 23.166667 \n",
"2017-06-16 20:20:00+02:00 -12088.862069 22.883333 23.066667 23.283333 \n",
"2017-06-16 20:25:00+02:00 -20.300000 22.666667 22.883333 23.066667 \n",
"2017-06-16 20:30:00+02:00 -33.517241 22.650000 22.666667 22.883333 \n",
"2017-06-16 20:35:00+02:00 -33.620690 22.800000 22.650000 22.666667 \n",
"... ... ... ... ... \n",
"2017-06-19 05:35:00+02:00 -3.000000 22.300000 22.316667 22.316667 \n",
"2017-06-19 05:40:00+02:00 -2.896552 22.300000 22.300000 22.316667 \n",
"2017-06-19 05:45:00+02:00 -3.433333 22.266667 22.300000 22.300000 \n",
"2017-06-19 05:50:00+02:00 -5.448276 22.116667 22.266667 22.300000 \n",
"2017-06-19 05:55:00+02:00 -3.241379 22.233333 22.116667 22.266667 \n",
"\n",
"[693 rows x 8 columns]"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"lu, ly = 1, 3\n",
"test_day = 3\n",
"df_test = load_autoregressive_df(test_day, lu = lu, ly = ly)\n",
"df_test"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [],
"source": [
"rand_idx = np.random.randint(0, len(df_test)- N_horizon)"
]
},
{
"cell_type": "code",
"execution_count": 151,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>SolRad</th>\n",
" <th>OutsideTemp</th>\n",
" <th>u</th>\n",
" <th>y</th>\n",
" <th>u_1</th>\n",
" <th>y_1</th>\n",
" <th>y_2</th>\n",
" <th>y_3</th>\n",
" </tr>\n",
" <tr>\n",
" <th>timestamp</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2017-06-17 18:10:00+02:00</th>\n",
" <td>468.033533</td>\n",
" <td>25.0</td>\n",
" <td>-6.931034</td>\n",
" <td>22.650000</td>\n",
" <td>-3531.200000</td>\n",
" <td>22.700000</td>\n",
" <td>22.700000</td>\n",
" <td>22.933333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:15:00+02:00</th>\n",
" <td>453.411767</td>\n",
" <td>25.0</td>\n",
" <td>-17.793103</td>\n",
" <td>22.966667</td>\n",
" <td>-6.931034</td>\n",
" <td>22.650000</td>\n",
" <td>22.700000</td>\n",
" <td>22.700000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:20:00+02:00</th>\n",
" <td>440.063033</td>\n",
" <td>25.0</td>\n",
" <td>-10028.379310</td>\n",
" <td>23.200000</td>\n",
" <td>-17.793103</td>\n",
" <td>22.966667</td>\n",
" <td>22.650000</td>\n",
" <td>22.700000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:25:00+02:00</th>\n",
" <td>425.747367</td>\n",
" <td>25.0</td>\n",
" <td>-13186.600000</td>\n",
" <td>23.200000</td>\n",
" <td>-10028.379310</td>\n",
" <td>23.200000</td>\n",
" <td>22.966667</td>\n",
" <td>22.650000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:30:00+02:00</th>\n",
" <td>411.838333</td>\n",
" <td>25.0</td>\n",
" <td>-13120.862069</td>\n",
" <td>23.033333</td>\n",
" <td>-13186.600000</td>\n",
" <td>23.200000</td>\n",
" <td>23.200000</td>\n",
" <td>22.966667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:35:00+02:00</th>\n",
" <td>398.560767</td>\n",
" <td>25.0</td>\n",
" <td>-13122.310345</td>\n",
" <td>22.866667</td>\n",
" <td>-13120.862069</td>\n",
" <td>23.033333</td>\n",
" <td>23.200000</td>\n",
" <td>23.200000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:40:00+02:00</th>\n",
" <td>385.483400</td>\n",
" <td>25.0</td>\n",
" <td>-10483.700000</td>\n",
" <td>22.733333</td>\n",
" <td>-13122.310345</td>\n",
" <td>22.866667</td>\n",
" <td>23.033333</td>\n",
" <td>23.200000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:45:00+02:00</th>\n",
" <td>370.694433</td>\n",
" <td>25.0</td>\n",
" <td>-11.793103</td>\n",
" <td>22.683333</td>\n",
" <td>-10483.700000</td>\n",
" <td>22.733333</td>\n",
" <td>22.866667</td>\n",
" <td>23.033333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:50:00+02:00</th>\n",
" <td>357.209133</td>\n",
" <td>25.0</td>\n",
" <td>-18.310345</td>\n",
" <td>22.850000</td>\n",
" <td>-11.793103</td>\n",
" <td>22.683333</td>\n",
" <td>22.733333</td>\n",
" <td>22.866667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2017-06-17 18:55:00+02:00</th>\n",
" <td>173.840733</td>\n",
" <td>25.0</td>\n",
" <td>-22.448276</td>\n",
" <td>23.000000</td>\n",
" <td>-18.310345</td>\n",
" <td>22.850000</td>\n",
" <td>22.683333</td>\n",
" <td>22.733333</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" SolRad OutsideTemp u y \\\n",
"timestamp \n",
"2017-06-17 18:10:00+02:00 468.033533 25.0 -6.931034 22.650000 \n",
"2017-06-17 18:15:00+02:00 453.411767 25.0 -17.793103 22.966667 \n",
"2017-06-17 18:20:00+02:00 440.063033 25.0 -10028.379310 23.200000 \n",
"2017-06-17 18:25:00+02:00 425.747367 25.0 -13186.600000 23.200000 \n",
"2017-06-17 18:30:00+02:00 411.838333 25.0 -13120.862069 23.033333 \n",
"2017-06-17 18:35:00+02:00 398.560767 25.0 -13122.310345 22.866667 \n",
"2017-06-17 18:40:00+02:00 385.483400 25.0 -10483.700000 22.733333 \n",
"2017-06-17 18:45:00+02:00 370.694433 25.0 -11.793103 22.683333 \n",
"2017-06-17 18:50:00+02:00 357.209133 25.0 -18.310345 22.850000 \n",
"2017-06-17 18:55:00+02:00 173.840733 25.0 -22.448276 23.000000 \n",
"\n",
" u_1 y_1 y_2 y_3 \n",
"timestamp \n",
"2017-06-17 18:10:00+02:00 -3531.200000 22.700000 22.700000 22.933333 \n",
"2017-06-17 18:15:00+02:00 -6.931034 22.650000 22.700000 22.700000 \n",
"2017-06-17 18:20:00+02:00 -17.793103 22.966667 22.650000 22.700000 \n",
"2017-06-17 18:25:00+02:00 -10028.379310 23.200000 22.966667 22.650000 \n",
"2017-06-17 18:30:00+02:00 -13186.600000 23.200000 23.200000 22.966667 \n",
"2017-06-17 18:35:00+02:00 -13120.862069 23.033333 23.200000 23.200000 \n",
"2017-06-17 18:40:00+02:00 -13122.310345 22.866667 23.033333 23.200000 \n",
"2017-06-17 18:45:00+02:00 -10483.700000 22.733333 22.866667 23.033333 \n",
"2017-06-17 18:50:00+02:00 -11.793103 22.683333 22.733333 22.866667 \n",
"2017-06-17 18:55:00+02:00 -18.310345 22.850000 22.683333 22.733333 "
]
},
"execution_count": 151,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_slice = df_test.iloc[rand_idx:rand_idx + N_horizon, :]\n",
"df_slice"
]
},
{
"cell_type": "code",
"execution_count": 152,
"metadata": {},
"outputs": [],
"source": [
"real_W = df_slice[['SolRad', 'OutsideTemp']].to_numpy()\n",
"real_x0 = df_slice.iloc[0,4:].to_numpy()"
]
},
{
"cell_type": "code",
"execution_count": 153,
"metadata": {},
"outputs": [],
"source": [
"real_p = casadi.vertcat(\n",
" casadi.vec(real_W),\n",
" casadi.vec(real_x0)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 154,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is Ipopt version 3.13.4, running with linear solver mumps.\n",
"NOTE: Other linear solvers might be more efficient (see Ipopt documentation).\n",
"\n",
"Number of nonzeros in equality constraint Jacobian...: 150\n",
"Number of nonzeros in inequality constraint Jacobian.: 10\n",
"Number of nonzeros in Lagrangian Hessian.............: 0\n",
"\n",
"Total number of variables............................: 70\n",
" variables with only lower bounds: 0\n",
" variables with lower and upper bounds: 0\n",
" variables with only upper bounds: 0\n",
"Total number of equality constraints.................: 60\n",
"Total number of inequality constraints...............: 10\n",
" inequality constraints with only lower bounds: 0\n",
" inequality constraints with lower and upper bounds: 10\n",
" inequality constraints with only upper bounds: 0\n",
"\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 0 3.9449223e+01 3.53e+03 2.64e-06 0.0 0.00e+00 - 0.00e+00 0.00e+00 0\n",
" 1 3.3074260e+01 1.22e+01 3.53e+03 -1.9 3.53e+03 - 9.90e-01 1.00e+00h 1\n",
" 2 2.1569451e+01 3.89e+00 1.04e+01 0.2 1.53e+01 - 9.98e-01 1.00e+00f 1\n",
" 3 1.2216613e+01 1.07e+00 2.03e+00 -1.8 9.82e+00 - 9.98e-01 1.00e+00f 1\n",
" 4 6.0768897e+00 2.46e-01 2.79e-01 -3.6 4.40e+00 - 1.00e+00 1.00e+00f 1\n",
" 5 5.4365914e+00 6.00e-03 1.57e-01 -5.5 9.64e-01 - 1.00e+00 1.00e+00h 1\n",
" 6 5.4343018e+00 1.05e-06 7.05e-03 -7.4 7.98e-03 - 1.00e+00 1.00e+00h 1\n",
" 7 5.4343047e+00 4.04e-07 1.35e-04 -9.4 1.19e-03 - 1.00e+00 1.00e+00h 1\n",
" 8 5.4343048e+00 2.43e-07 2.99e-04 -11.0 1.51e-03 - 1.00e+00 1.00e+00h 1\n",
" 9 5.4343030e+00 5.92e-07 4.18e-03 -11.0 5.49e-03 - 1.00e+00 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 10 5.4332567e+00 8.43e-04 1.69e-02 -11.0 2.28e+00 - 1.00e+00 1.00e+00h 1\n",
" 11 5.4346201e+00 8.74e-07 5.02e-03 -11.0 2.48e+00 - 1.00e+00 1.00e+00H 1\n",
" 12 5.4274576e+00 2.72e-03 1.08e-02 -11.0 1.54e+01 - 1.00e+00 1.00e+00f 1\n",
" 13 5.4332922e+00 8.83e-04 2.52e-03 -11.0 5.14e+00 - 1.00e+00 1.00e+00h 1\n",
" 14 5.3426257e+00 3.42e-02 1.47e-02 -11.0 2.93e+02 - 1.00e+00 1.00e+00f 1\n",
" 15 5.2809047e+00 7.25e-02 1.14e-02 -11.0 1.94e+02 - 1.00e+00 1.00e+00h 1\n",
" 16 5.2454961e+00 5.67e-01 2.83e-01 -11.0 2.55e+03 - 1.00e+00 5.00e-01f 2\n",
" 17 4.2900853e+00 8.09e-01 2.57e-01 -11.0 4.79e+03 - 1.00e+00 1.00e+00f 1\n",
" 18 3.9872017e+00 8.01e-01 4.15e-01 -9.0 2.46e+03 - 1.00e+00 7.25e-01h 1\n",
" 19 3.9828024e+00 7.97e-01 4.09e-01 -7.1 5.10e+03 - 1.00e+00 4.86e-03h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 20 3.9955347e+00 7.62e-01 3.91e-01 -11.0 1.40e+04 - 2.59e-05 3.92e-02h 4\n",
" 21 3.3230445e+00 1.62e+00 7.43e-01 -5.9 2.58e+04 - 1.00e+00 1.94e-01f 1\n",
" 22 3.3159554e+00 1.63e+00 7.40e-01 -4.0 3.81e+04 - 1.00e+00 1.16e-03h 1\n",
" 23 5.7610224e+00 6.56e-01 6.33e-01 -3.2 4.68e+03 - 1.00e+00 1.00e+00h 1\n",
" 24 4.8314850e+00 1.14e+00 4.89e-01 -2.8 1.39e+04 - 2.21e-02 1.89e-01f 1\n",
" 25 3.9298440e+00 4.53e-01 3.48e-01 -2.8 1.13e+04 - 4.04e-03 6.29e-01F 1\n",
" 26 3.8422684e+00 4.44e-01 3.34e-01 -2.4 2.98e+04 - 1.00e+00 2.03e-02h 1\n",
" 27 3.9181611e+00 4.44e-01 3.40e-01 -1.5 1.15e+04 - 8.34e-01 8.61e-02f 4\n",
" 28 3.9145141e+00 4.66e-01 4.14e-01 -1.6 2.37e+04 - 4.26e-01 3.76e-02f 3\n",
" 29 4.3665645e+00 5.75e-01 2.13e-01 -1.6 3.11e+03 - 7.82e-01 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 30 4.1588261e+00 4.47e-01 2.07e-01 -1.6 2.24e+04 - 2.27e-01 8.93e-02f 2\n",
" 31 4.0448026e+00 4.88e-01 8.52e-02 -1.6 3.54e+03 - 1.00e+00 1.00e+00h 1\n",
" 32 4.3320693e+00 5.01e-01 3.13e-01 -1.6 3.09e+03 - 6.34e-01 7.31e-01h 1\n",
" 33 4.4114252e+00 5.90e-01 1.65e-01 -2.0 1.67e+03 - 2.89e-01 1.00e+00h 1\n",
" 34 4.2453997e+00 4.46e-01 5.76e-01 -2.4 1.03e+04 - 7.27e-01 6.28e-01h 1\n",
" 35 4.2395100e+00 4.34e-01 5.37e-01 -2.3 2.96e+04 - 4.78e-01 2.52e-02h 4\n",
" 36 4.1425759e+00 4.22e-01 3.66e-01 -2.3 3.87e+04 - 3.22e-01 1.71e-01f 1\n",
" 37 4.0746738e+00 5.26e-01 2.19e-01 -2.3 1.64e+04 - 1.00e+00 1.81e-01h 1\n",
" 38 4.6831446e+00 1.33e-02 9.95e-01 -2.3 1.14e+00 - 1.00e+00 1.00e+00h 1\n",
" 39 4.6652006e+00 4.38e-06 5.08e-03 -3.8 4.05e-02 - 1.00e+00 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 40 4.6651849e+00 7.40e-06 5.83e-03 -5.9 8.43e-03 - 1.00e+00 1.00e+00h 1\n",
" 41 4.6652003e+00 2.78e-06 4.05e-03 -8.0 6.53e-03 - 1.00e+00 1.00e+00h 1\n",
" 42 4.6652078e+00 1.86e-06 5.11e-03 -9.9 4.00e-03 - 1.00e+00 1.00e+00h 1\n",
" 43 4.6652106e+00 4.89e-07 2.49e-03 -10.9 2.45e-03 - 1.00e+00 1.00e+00h 1\n",
" 44 4.6652070e+00 1.06e-06 4.96e-03 -11.0 3.14e-03 - 1.00e+00 1.00e+00h 1\n",
" 45 4.6652107e+00 6.94e-07 3.39e-03 -11.0 1.12e-03 - 1.00e+00 1.00e+00h 1\n",
" 46 4.6652021e+00 5.56e-06 5.86e-03 -11.0 1.26e-02 - 1.00e+00 1.00e+00h 1\n",
" 47 4.6651896e+00 5.80e-06 9.52e-03 -11.0 1.90e-02 - 1.00e+00 1.00e+00h 1\n",
" 48 4.6652034e+00 2.35e-06 2.98e-03 -11.0 1.07e-02 - 1.00e+00 1.00e+00h 1\n",
" 49 4.6651482e+00 3.84e-05 7.09e-03 -11.0 9.42e-02 - 1.00e+00 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 50 4.6651476e+00 3.65e-05 6.57e-03 -11.0 1.46e-01 - 1.00e+00 1.00e+00h 1\n",
" 51 4.6650378e+00 4.94e-05 3.35e-03 -11.0 1.21e-01 - 1.00e+00 1.00e+00h 1\n",
" 52 4.6652080e+00 4.06e-08 2.12e-04 -11.0 1.11e-01 - 1.00e+00 1.00e+00H 1\n",
" 53 4.6651547e+00 1.97e-05 6.76e-03 -11.0 5.50e-02 - 1.00e+00 1.00e+00h 1\n",
" 54 4.6651784e+00 9.13e-06 4.15e-03 -11.0 6.17e-02 - 1.00e+00 1.00e+00h 1\n",
" 55 4.6649440e+00 9.23e-05 6.02e-03 -9.0 4.45e-01 - 1.00e+00 5.73e-01h 1\n",
" 56 4.6649432e+00 9.22e-05 4.84e-03 -7.8 7.87e+00 - 1.00e+00 8.18e-05h 1\n",
" 57 4.6651975e+00 6.30e-06 4.13e-03 -8.7 1.35e-02 - 1.00e+00 1.00e+00h 1\n",
" 58 4.6651975e+00 1.19e-06 2.69e-03 -8.8 4.23e-03 - 1.00e+00 1.00e+00h 1\n",
" 59 4.6651790e+00 1.48e-05 5.20e-03 -8.2 4.30e-02 - 1.00e+00 1.00e+00h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 60 4.6651741e+00 1.16e-05 3.92e-03 -8.3 5.02e-02 - 5.68e-01 1.00e+00h 1\n",
" 61 4.6651894e+00 1.27e-05 5.60e-03 -8.2 6.33e-02 - 1.00e+00 1.00e+00h 1\n",
" 62 4.6645492e+00 1.34e-03 6.23e-03 -7.0 5.65e+00 - 3.71e-01 1.00e+00h 1\n",
" 63 4.3495224e+00 1.79e-01 1.39e-01 -7.7 2.10e+03 - 1.00e+00 4.15e-01f 1\n",
" 64 3.8812429e+00 6.92e-01 1.77e-01 -4.3 4.25e+03 - 4.16e-02 1.00e+00f 1\n",
" 65 3.8556488e+00 9.02e-01 5.64e-01 -3.7 4.62e+03 - 5.59e-01 1.00e+00f 1\n",
" 66 3.3532482e+00 1.10e+00 4.45e-01 -3.7 2.35e+05 - 2.08e-02 1.06e-02f 1\n",
" 67 4.1857330e+00 5.13e-01 2.71e-01 -3.3 1.25e+04 - 1.00e+00 5.45e-01h 1\n",
" 68 3.9064264e+00 7.77e-01 2.48e-01 -3.4 9.49e+03 - 5.24e-02 3.44e-01h 1\n",
" 69 4.5883140e+00 5.74e-01 2.74e-01 -3.4 3.49e+03 - 8.49e-01 9.57e-01h 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 70 4.2716175e+00 4.48e-01 1.56e-01 -3.4 7.97e+03 - 6.82e-03 1.99e-01h 1\n",
" 71 4.4376261e+00 8.41e-01 1.09e-01 -3.4 3.06e+03 - 7.11e-01 1.00e+00h 1\n",
" 72 4.2718628e+00 8.02e-01 1.24e-01 -3.4 3.96e+03 - 7.79e-01 2.74e-01h 1\n",
" 73 4.1692502e+00 8.15e-01 1.06e-01 -3.4 4.59e+03 - 8.05e-03 2.42e-01h 1\n",
" 74 4.1787226e+00 7.74e-01 1.32e-01 -3.4 6.16e+03 - 3.97e-01 5.92e-02h 1\n",
" 75 4.8354108e+00 5.18e-01 1.24e-01 -3.4 1.72e+03 - 1.00e+00 6.20e-01H 1\n",
" 76 4.6938939e+00 5.47e-01 1.66e-01 -3.4 1.90e+04 - 2.02e-01 4.54e-02h 2\n",
" 77 4.9988408e+00 4.89e-01 3.45e-01 -3.4 5.66e+03 - 2.14e-01 9.92e-01h 1\n",
" 78 4.8499839e+00 4.26e-01 3.75e-01 -3.4 1.14e+04 - 7.42e-04 6.53e-02f 1\n",
" 79 4.3375958e+00 6.40e-01 5.48e-02 -3.4 5.40e+03 - 1.00e+00 1.00e+00F 1\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 80 3.9034327e+00 5.38e-01 3.06e-01 -3.4 9.68e+03 - 3.65e-01 6.23e-01F 1\n",
" 81 5.5758732e+00 8.59e-01 5.26e-01 -3.2 2.16e+03 - 5.65e-01 1.00e+00h 1\n",
" 82 5.0529427e+00 5.22e-01 3.17e-01 -2.8 3.58e+03 - 1.00e+00 3.77e-01f 1\n",
" 83 4.9564772e+00 1.45e+00 8.63e-01 -2.8 9.04e+03 - 1.43e-01 5.36e-01f 1\n",
" 84 4.8642573e+00 1.29e+00 8.13e-01 -2.8 5.32e+03 - 7.63e-01 9.94e-02h 1\n",
" 85 4.4360592e+00 9.26e-01 6.08e-01 -2.8 7.53e+03 - 6.61e-02 9.55e-01f 1\n",
" 86 4.3526499e+00 8.61e-01 5.90e-01 -2.8 2.14e+03 - 8.04e-01 5.99e-02h 1\n",
" 87 4.6534935e+00 4.66e-01 1.12e-01 -2.8 3.74e+03 - 1.22e-02 6.65e-01H 1\n",
" 88 4.5693769e+00 4.42e-01 8.36e-02 -2.8 4.24e+03 - 8.34e-01 8.93e-02h 1\n",
" 89 3.8390277e+00 5.35e-01 4.87e-01 -2.8 1.30e+04 - 4.88e-02 1.03e-01f 3\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 90 3.6653054e+00 5.12e-01 2.34e-01 -2.5 2.66e+04 - 6.48e-01 7.35e-02f 1\n",
" 91 3.6674015e+00 5.23e-01 1.59e-01 -1.7 3.17e+04 - 5.25e-01 1.50e-02h 4\n",
" 92 3.5710253e+00 9.15e-01 4.40e-01 -1.2 5.11e+04 - 2.61e-01 7.14e-02f 2\n",
" 93 4.5652538e+00 7.65e-01 4.59e-01 -2.7 1.29e+04 - 1.87e-01 9.39e-01H 1\n",
" 94 4.2994338e+00 5.43e-01 2.13e-01 -1.9 6.20e+03 - 1.00e+00 4.26e-01F 1\n",
" 95 4.2721384e+00 6.11e-01 2.31e-01 -1.9 2.70e+04 - 1.33e-01 6.11e-02h 2\n",
" 96 4.5982599e+00 5.45e-01 3.94e-01 -1.9 4.18e+03 - 3.25e-01 1.00e+00H 1\n",
" 97 4.5955406e+00 6.97e-01 3.95e-01 -1.9 1.64e+04 - 2.74e-01 1.60e-02h 5\n",
" 98 4.4487534e+00 5.66e-01 3.66e-01 -1.9 9.27e+03 - 2.35e-01 4.40e-01f 1\n",
" 99 4.1725592e+00 8.99e-01 2.72e-01 -1.9 1.72e+05 - 4.06e-02 3.19e-02f 2\n",
"iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n",
" 100 4.9563901e+00 3.62e-01 2.72e-01 -1.9 6.55e+03 - 2.14e-01 5.29e-01h 1\n",
"\n",
"Number of Iterations....: 100\n",
"\n",
" (scaled) (unscaled)\n",
"Objective...............: 4.9563901175171567e+00 4.9563901175171567e+00\n",
"Dual infeasibility......: 2.7174260006204348e-01 2.7174260006204348e-01\n",
"Constraint violation....: 3.6196146876667257e-01 3.6196146876667257e-01\n",
"Complementarity.........: 1.5305110259329480e-02 1.5305110259329480e-02\n",
"Overall NLP error.......: 3.6196146876667257e-01 3.6196146876667257e-01\n",
"\n",
"\n",
"Number of objective function evaluations = 168\n",
"Number of objective gradient evaluations = 101\n",
"Number of equality constraint evaluations = 168\n",
"Number of inequality constraint evaluations = 168\n",
"Number of equality constraint Jacobian evaluations = 101\n",
"Number of inequality constraint Jacobian evaluations = 101\n",
"Number of Lagrangian Hessian evaluations = 0\n",
"Total CPU secs in IPOPT (w/o function evaluations) = 9.102\n",
"Total CPU secs in NLP function evaluations = 940.749\n",
"\n",
"EXIT: Maximum Number of Iterations Exceeded.\n",
" solver : t_proc (avg) t_wall (avg) n_eval\n",
" nlp_f | 29.13 s (173.38ms) 23.38 s (139.16ms) 168\n",
" nlp_g | 25.97 s (154.56ms) 20.73 s (123.42ms) 168\n",
" nlp_grad | 9.50 s ( 9.50 s) 7.37 s ( 7.37 s) 1\n",
" nlp_grad_f | 523.87 s ( 5.14 s) 419.30 s ( 4.11 s) 102\n",
" nlp_jac_g | 456.46 s ( 4.48 s) 365.04 s ( 3.58 s) 102\n",
" total | 1.05ks ( 1.05ks) 836.05 s (836.05 s) 1\n"
]
},
{
"data": {
"text/plain": [
"DM([468.034, 453.412, 440.063, 425.747, 411.838, 398.561, 385.483, 370.694, 357.209, 173.841, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2732.92, 6198.29, -3878.46, 1639.7, 6123.03, -16585.5, 217.313, -14943.5, 6266.88, 49.1826, -3531.2, 2732.92, 6198.29, -3878.46, 1639.7, 6123.03, -16585.5, 217.313, -14943.5, 6266.88, 22.7, 22.7127, 22.9458, 23.1872, 23.5197, 23.7701, 23.6996, 23.6523, 23.7526, 23.9052, 22.7, 22.7, 22.7127, 22.9458, 23.1872, 23.5197, 23.7701, 23.6996, 23.6523, 23.7526, 22.9333, 22.7, 22.7, 22.7127, 22.9458, 23.1872, 23.5197, 23.7701, 23.6996, 23.6523])"
]
},
"execution_count": 154,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res = solver(p = real_p, lbg = real_lbg, ubg = real_ubg)\n",
"res['x']"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'f': DM(4.40448),\n",
" 'g': DM([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.00470767, 0, 0, 0, -0.113089, 0, 0, 0, 0.0784758, 0, 0, 0, -0.260693, 0, 0, 0, 0.357126, 0, 0, 0, 0.669296, 0, 0, 0, 0.68248, 0, 0, 0, -0.247434, 0, 0, 0, 0.19414, 0, 0]),\n",
" 'lam_g': DM([0.00058908, 3.08326, -0.356412, -0.423444, 0.000371174, 0.000534039, -5.21535e-05, -0.000138734, 5.69737e-05, 5.3783e-05, 0.000187072, 0.000149544, 0.000114475, 3.09363e-06, 0.0420244, 0.0331837, 0.0236642, 0.0183999, 0.0143155, 0.0123639, 0.00744731, 0.00510669, 0.00291009, 0.000884082, 1.91038e-06, 2.43046, -0.265973, -0.332856, 4.74083e-05, 1.82938, -0.195364, -0.246757, 6.22741e-05, 1.35846, -0.15016, -0.180631, -2.68583e-05, 1.08861, -0.120118, -0.138914, -6.83068e-05, 0.917211, -0.0855439, -0.111596, -0.000115542, 0.624076, -0.0576698, -0.0785685, 5.21615e-05, 0.445059, -0.0326176, -0.0531857, 1.60475e-05, 0.237493, -0.0111887, -0.0298096, 6.34075e-06, 0.0680819, -0.000572791, -0.0094662]),\n",
" 'lam_p': DM([0.000371174, 0.000534039, -5.21535e-05, -0.000138734, 5.69737e-05, 5.3783e-05, 0.000187072, 0.000149544, 0.000114475, 3.09363e-06, 0.0420244, 0.0331837, 0.0236642, 0.0183999, 0.0143155, 0.0123639, 0.00744731, 0.00510669, 0.00291009, 0.000884082, 0.00058908, 3.08326, -0.356412, -0.423444]),\n",
" 'lam_x': DM([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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),\n",
" 'x': DM([468.034, 453.412, 440.063, 425.747, 411.838, 398.561, 385.483, 370.694, 357.209, 173.841, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 8591.02, 61193.3, 50051, -8345.25, -162558, -4321.95, -72714.8, 5555.41, 14341.3, -3961.87, -3531.2, 8591.02, 61193.3, 50051, -8345.25, -162558, -4321.95, -72714.8, 5555.41, 14341.3, 22.7, 22.7182, 22.8375, 23.9545, 24.7475, 25.429, 24.0712, 24.7132, 23.4304, 23.7047, 22.7, 22.7, 22.7182, 22.8375, 23.9545, 24.7475, 25.429, 24.0712, 24.7132, 23.4304, 22.9333, 22.7, 22.7, 22.7182, 22.8375, 23.9545, 24.7475, 25.429, 24.0712, 24.7132])}"
]
},
"execution_count": 86,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res"
]
},
{
"cell_type": "code",
"execution_count": 155,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>0</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>468.033533</td>\n",
" <td>25.0</td>\n",
" <td>2732.916493</td>\n",
" <td>-3531.200000</td>\n",
" <td>22.700000</td>\n",
" <td>22.700000</td>\n",
" <td>22.933333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>453.411767</td>\n",
" <td>25.0</td>\n",
" <td>6198.288267</td>\n",
" <td>2732.916493</td>\n",
" <td>22.712653</td>\n",
" <td>22.700000</td>\n",
" <td>22.700000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>440.063033</td>\n",
" <td>25.0</td>\n",
" <td>-3878.457834</td>\n",
" <td>6198.288267</td>\n",
" <td>22.945795</td>\n",
" <td>22.712653</td>\n",
" <td>22.700000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>425.747367</td>\n",
" <td>25.0</td>\n",
" <td>1639.701692</td>\n",
" <td>-3878.457834</td>\n",
" <td>23.187228</td>\n",
" <td>22.945795</td>\n",
" <td>22.712653</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>411.838333</td>\n",
" <td>25.0</td>\n",
" <td>6123.032937</td>\n",
" <td>1639.701692</td>\n",
" <td>23.519734</td>\n",
" <td>23.187228</td>\n",
" <td>22.945795</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>398.560767</td>\n",
" <td>25.0</td>\n",
" <td>-16585.507739</td>\n",
" <td>6123.032937</td>\n",
" <td>23.770119</td>\n",
" <td>23.519734</td>\n",
" <td>23.187228</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>385.483400</td>\n",
" <td>25.0</td>\n",
" <td>217.313208</td>\n",
" <td>-16585.507739</td>\n",
" <td>23.699578</td>\n",
" <td>23.770119</td>\n",
" <td>23.519734</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>370.694433</td>\n",
" <td>25.0</td>\n",
" <td>-14943.460194</td>\n",
" <td>217.313208</td>\n",
" <td>23.652328</td>\n",
" <td>23.699578</td>\n",
" <td>23.770119</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>357.209133</td>\n",
" <td>25.0</td>\n",
" <td>6266.876146</td>\n",
" <td>-14943.460194</td>\n",
" <td>23.752610</td>\n",
" <td>23.652328</td>\n",
" <td>23.699578</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>173.840733</td>\n",
" <td>25.0</td>\n",
" <td>49.182629</td>\n",
" <td>6266.876146</td>\n",
" <td>23.905214</td>\n",
" <td>23.752610</td>\n",
" <td>23.652328</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 0 1 2 3 4 5 \\\n",
"0 468.033533 25.0 2732.916493 -3531.200000 22.700000 22.700000 \n",
"1 453.411767 25.0 6198.288267 2732.916493 22.712653 22.700000 \n",
"2 440.063033 25.0 -3878.457834 6198.288267 22.945795 22.712653 \n",
"3 425.747367 25.0 1639.701692 -3878.457834 23.187228 22.945795 \n",
"4 411.838333 25.0 6123.032937 1639.701692 23.519734 23.187228 \n",
"5 398.560767 25.0 -16585.507739 6123.032937 23.770119 23.519734 \n",
"6 385.483400 25.0 217.313208 -16585.507739 23.699578 23.770119 \n",
"7 370.694433 25.0 -14943.460194 217.313208 23.652328 23.699578 \n",
"8 357.209133 25.0 6266.876146 -14943.460194 23.752610 23.652328 \n",
"9 173.840733 25.0 49.182629 6266.876146 23.905214 23.752610 \n",
"\n",
" 6 \n",
"0 22.933333 \n",
"1 22.700000 \n",
"2 22.700000 \n",
"3 22.712653 \n",
"4 22.945795 \n",
"5 23.187228 \n",
"6 23.519734 \n",
"7 23.770119 \n",
"8 23.699578 \n",
"9 23.652328 "
]
},
"execution_count": 155,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_results = pd.DataFrame(np.array(res['x'].reshape((N_horizon, -1))))\n",
"df_results"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'np' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-2-acd52bfe0cdc>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mN_horizon\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'np' is not defined"
]
}
],
"source": [
"np.array(res['x'].reshape((N_horizon, -1)))"
]
},
{
"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.9.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}