{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Testing the performance of VOPy\n", "This notebook contains a comparison of VOPy implementations and of naive implementations of confidence region operation that checks domination and Pareto set calculation." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "import cvxpy as cp\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "from vopy.utils import (\n", " set_seed,\n", " hyperrectangle_get_vertices,\n", " hyperrectangle_get_region_matrix,\n", ")\n", "from vopy.order import ConeTheta2DOrder\n", "from vopy.confidence_region import (\n", " RectangularConfidenceRegion,\n", " confidence_region_check_dominates,\n", ")\n", "\n", "set_seed(0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create an `Order` object to do the comparisions with. We can visualize it's cone." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/png": "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cnPVyZO3bq6a6XfNlWq1Wp3fxwXm29TUVAwNDcXk5GQMDg42+nGA/7h0KX+9/eyzd/9si2+XBIDGGRiYWRhHCGQAKIJABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKIBABoACCGQAKEClWq1WG/0QwOxUq9W4dOlSDAwMRKVSafTjAPdBIANAAYysAaAAAhkACiCQAaAAAhkACiCQAaAAAhkACiCQAaAA/w+CtcwmsZHV3QAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "order = ConeTheta2DOrder(cone_degree=135)\n", "fig_cone = order.ordering_cone.plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Check dominates performance" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Following define utilities for generating random rectangles and visualizing them. We can see the visualization of two random rectangles below." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def order_vertices_clockwise(vertices):\n", " # Sort the vertices in clockwise order.\n", " center = np.mean(vertices, axis=0)\n", " angles = np.arctan2(vertices[:, 1] - center[1], vertices[:, 0] - center[0])\n", " return vertices[np.argsort(angles)]\n", "\n", "def plot_rectangle(vertices, ax, label):\n", " len_vert = len(vertices)\n", " \n", " # Plot the points.\n", " ax.scatter(vertices[:, 0], vertices[:, 1], label=label)\n", " \n", " # Plot the edges of the rectangle by connecting the vertices.\n", " for i in range(len_vert):\n", " ax.plot(vertices[[i, (i+1)%len_vert], 0], vertices[[i, (i+1)%len_vert], 1], 'k-')\n", "\n", "def visualize_comparison(rect1, rect2):\n", " fig, ax = plt.subplots(1, 1, figsize=(6, 4))\n", "\n", " # Plot each polytope with a different label\n", " rects = [rect1, rect2]\n", " labels = [r\"$x$\", r\"$x'$\"]\n", " for rect, label in zip(rects, labels):\n", " vertices = hyperrectangle_get_vertices(rect.lower, rect.upper)\n", " vertices = order_vertices_clockwise(vertices) # Order the vertices in clockwise order.\n", " plot_rectangle(vertices, ax, label)\n", "\n", " ax.set_xlabel(r'$y_1$ Axis')\n", " ax.set_ylabel(r'$y_2$ Axis')\n", " plt.legend()\n", " plt.show()\n", "\n", "def generate_rectangle():\n", " dim = 2\n", " center = 3 * np.random.randn(dim)\n", " size = 4 * np.random.rand(dim) + 1e-2\n", " lower = center - size\n", " upper = center + size\n", " return RectangularConfidenceRegion(dim, lower, upper)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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U+/evXXbbbdp/fr1SkhI0FdffaWmTZtaHS3g5eXlqbKy0vN8z5496t+/v0aPHm1hqtBB0bDA8OHDaz1/6qmnlJWVpY8++oii4SNlZWUaO3asli1bpvnz51sdJ2iEh4czimHIH/7wB6WkpCg7O9uzrG3bttYFCiItWrSo9XzBggVq3769br31VosShRYunVissrJSb775psrLy9WzZ0+r4wSNqVOnaujQobrjjjusjhJUvvjiC7Vq1Urt2rXTmDFjdODAAasjBY21a9cqIyNDo0ePVkJCgm688UYtW7bM6lhB5/Tp03rttdc0YcIES36ZZiiiaFhk9+7diomJUWRkpCZPnqycnBylpqZaHSsovPnmm8rPz1dmZqbVUYJK9+7dtWLFCm3cuFHLli1TcXGxevXqpW+//dbqaEHhwIEDysrK0nXXXaeNGzdq8uTJeuihh7RixQqrowWVd955R99//73uu+8+q6OEDD4Z1CKnT5/W4cOH9f3332v16tX64x//qA8++ICyUU8FBQXKyMhQbm6uunTpIknq27evunbtqkWLFlkbLsiUl5erffv2euSRRzRjxgyr4wS8iIgIZWRkaNu2bZ5lDz30kPLy8vS3v/3NwmTBZeDAgYqIiNC6deusjhIyGNGwSEREhK699lplZGQoMzNTXbp00fPPP291rIC3c+dOlZSUKD09XeHh4QoPD9cHH3ygxYsXKzw8vNaEMNRPkyZNdMMNN+iLL76wOkpQSEpKuuB/NDp27KjDhw9blCj4HDp0SJs3b9akSZOsjhJSmAzqJ9xutyoqKqyOEfD69eun3bt311p2//336/rrr9fvf/977pLwoYqKCu3bt099+vSxOkpQ6N27t/bv319r2T/+8Q+1adPGokTBJzs7WwkJCRo6dKjVUUIKRcMCs2bN0uDBg5WSkqLS0lK9+eab2rJlizZs2GB1tIAXGxurzp0711rWpEkTNW/e/ILlqJt///d/1/Dhw3X11VerpKRE8+fPl8vl0r333mt1tKDwu9/9Tr169dLTTz+tu+++Wzt27NDSpUu1dOlSq6MFhaqqKmVnZ+vee+9VeDinvobEu22Bo0ePavz48SoqKpLD4VBaWpo2bNig/v37Wx0NuKRvvvlGv/71r3X8+HG1aNFCPXr00EcffcT/cftIt27dlJOTo5kzZ+rJJ59Uu3bttGjRIo0dO9bqaEFh8+bNOnz4sCZMmGB1lJDDZFAAAGAMk0EBAIAxFA0AAGAMRQMAABhD0QAAAMZQNAAAgDEUDQAAYAxFAwAAGEPRAAAAxlA0AACAMRQNAEGnb9++mj59utUxAIiPIAfgh7Zt26Y+ffqof//+Xv2ywRMnTqhRo0aKjY01kA5AXVA0APidSZMmKSYmRn/84x+1d+9eXX311VZHAuAlLp0AqJfk5GS9+OKLtZZt27ZN0dHROnToUJ23V15errfffltTpkzRsGHD9Morr9R6/dixY0pMTNTTTz/tWbZ9+3ZFREQoNzdX0oWXTlatWqUbbrhBjRs3VvPmzXXHHXeovLy8ztkA1B1FA0C99OjRQ3l5eZ7nbrdb06dP1/Tp0736FfJvvfWWOnTooA4dOmjcuHHKzs5WzYHXFi1a6OWXX9bcuXP18ccfq6ysTOPGjdODDz6oAQMGXLC9oqIi/frXv9aECRO0b98+bdmyRSNHjhSDuUDDoGgAqJefFo1XX31Vhw8f1syZMyVJd911l6666iqNGjXqira3fPlyjRs3TpI0aNAglZWV6b333qu1zpAhQ/TAAw9o7Nixmjx5sqKiorRgwYKLbq+oqEhnz57VyJEj1bZtW91www168MEHFRMT482PC6COKBoA6qVHjx7at2+fysrKdPLkSc2aNUvz58/3TMR86KGHtGLFiiva1v79+7Vjxw6NGTNGkhQeHq577rlHL7/88gXrLly4UGfPntXbb7+t119/XVFRURfdZpcuXdSvXz/dcMMNGj16tJYtW6bvvvvOy58WQF1RNADUS0ZGhsLCwpSfn68FCxaoefPmmjBhguf122677Yrv/li+fLnOnj2r1q1bKzw8XOHh4crKytKf//znC8rBgQMHVFhYqKqqqsvOBQkLC9OmTZu0fv16paamasmSJerQoYO+/vpr735gAHVC0QBQL1FRUerSpYv+/Oc/a+HChXruuedkt9f90HL27FmtWLFCzz77rD755BPP49NPP1WbNm30+uuve9Y9ffq0xo4dq3vuuUfz58/XxIkTdfTo0Utu22azqXfv3po3b5527dqliIgI5eTkePXzAqibcKsDAAh8PXr00OLFizVs2DD169fPq228++67+u677zRx4kQ5HI5ar40aNUrLly/XtGnTJEmzZ8+W0+nU4sWLFRMTo/Xr12vixIl69913L9ju9u3b9d5772nAgAFKSEjQ9u3bdezYMXXs2NGrnADqhhENAPXWtWtXhYeH65lnnvF6G8uXL9cdd9xxQcmQpF/96lf65JNPlJ+fry1btmjRokV69dVXFRcXJ7vdrldffVV/+ctflJWVdcH3xsXF6cMPP9SQIUP0i1/8Qo899pieffZZDR482OusAK4cH9gFoN5uv/12paWladGiRRd9fcuWLXrhhRe0atWqhg0GwHJcOgHglaqqKh07dkzLly/X/v37LznnYeDAgcrPz1d5ebmSk5OVk5Ojbt26NXBaAFZhRAOAV7Zs2aLbb79d119/vbKzs9W9e3erIwHwQxQNAABgDJNBAQCAMRQNAABgDEUDAAAYQ9EAAADGUDQAAIAxFA0AAGAMRQMAABhD0QAAAMZQNAAAgDEUDQAAYAxFAwAAGPP/AWX8O9Qa6Gj+AAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = generate_rectangle()\n", "x_prime = generate_rectangle()\n", "\n", "visualize_comparison(x, x_prime)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define the check dominates function to check if the first rectangle dominates the second one, using the definition in [Korkmaz et al. 2024](https://arxiv.org/abs/2412.02484) to formulate convex optimization problem. Efficient VOPy implementation is in `vopy.confidence_region.RectangularConfidenceRegion.check_dominates`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def check_dominates_naive(order, rect1, rect2, slackness=0):\n", " vertices = hyperrectangle_get_vertices(rect1.lower, rect1.upper)\n", " obj2_matrix, obj2_boundary = hyperrectangle_get_region_matrix(rect2.lower, rect2.upper)\n", "\n", " m = order.ordering_cone.W.shape[1]\n", "\n", " for vertex in vertices:\n", " x = cp.Variable(m)\n", " y = cp.Variable(m)\n", " prob = cp.Problem(\n", " cp.Minimize(0),\n", " [\n", " x + y == vertex,\n", " obj2_matrix @ x >= obj2_boundary,\n", " order.ordering_cone.W @ y >= 0,\n", " ],\n", " )\n", " try:\n", " prob.solve()\n", " except cp.error.SolverError:\n", " prob.solve(solver=cp.SCS)\n", "\n", " if prob.status == \"infeasible\":\n", " return False\n", "\n", " return True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compare computation time of this with native VOPy implementation." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "VOPy time: 0.0898141860961914, Naive time: 17.23957848548889\n" ] } ], "source": [ "iter_cnt = 5000\n", "rects = [[generate_rectangle(), generate_rectangle()] for _ in range(iter_cnt)]\n", "\n", "vopy_start = time.time()\n", "for i, (x, x_prime) in enumerate(rects):\n", " confidence_region_check_dominates(order, x, x_prime)\n", "vopy_time = time.time() - vopy_start\n", "\n", "naive_start = time.time()\n", "for i, (x, x_prime) in enumerate(rects):\n", " naive_result = check_dominates_naive(order, x, x_prime)\n", "naive_time = time.time() - naive_start\n", "\n", "print(f\"VOPy time: {vopy_time}, Naive time: {naive_time}\")\n", "\n", "for i, (x, x_prime) in enumerate(rects):\n", " vopy_result = confidence_region_check_dominates(order, x, x_prime)\n", " naive_result = check_dominates_naive(order, x, x_prime)\n", " if vopy_result != naive_result:\n", " print(f\"VOPy: {vopy_result}, Naive: {naive_result}\")\n", " visualize_comparison(x, x_prime)\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pareto set calculation performance" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's now look at the Pareto set calculation performance w.r.t. the cardinality of the domain. Naive implementation with for-loops is already present in the `Order` class." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "vopy_times = []\n", "naive_times = []\n", "\n", "pts_all = np.random.randn(10000, 2)\n", "pt_cnts = np.linspace(100, 10000, 25, dtype=int)\n", "for pt_cnt in pt_cnts:\n", " pts = pts_all[:pt_cnt]\n", "\n", " vopy_start = time.time()\n", " p_set_vopy = order.get_pareto_set(pts)\n", " vopy_time = time.time() - vopy_start\n", "\n", " naive_start = time.time()\n", " p_set_naive = order.get_pareto_set_naive(pts)\n", " naive_time = time.time() - naive_start\n", "\n", " vopy_times.append(vopy_time)\n", " naive_times.append(naive_time)\n", "\n", " assert set(sorted(p_set_vopy)) == set(sorted(p_set_naive))\n", "\n", "fig, ax = plt.subplots(1, 1, figsize=(6, 4))\n", "ax.plot(pt_cnts, vopy_times, c='tab:blue', label='VOPy')\n", "ax.plot(pt_cnts, naive_times, c='tab:red', label='Naive')\n", "ax.set_xlabel(r'$\\vert \\mathcal{X} \\vert$')\n", "ax.set_ylabel('Time (s)')\n", "ax.legend()\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 2 }