{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "vscode": {
     "languageId": "plaintext"
    }
   },
   "source": [
    "# Linear feasibility seeking models"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the following linear problems there exist dedicated feasibility seeking implementations that take advantage of matrix operations:\n",
    "- **Hyperplanes:** $Ax = b$ \n",
    "- **Halfspaces:** $Ax \\leq b$\n",
    "- **Hyperslabs/Bands:** $lb \\leq Ax \\leq ub$ \n",
    "\n",
    "All have implementations for the AMS algorithm/Kazmarz method in sequential, simultaneous, block iterative, as well as string averaged formulation.\n",
    "\n",
    "These can be accessed e.g. via the following classes from the `suppy.feasibility` module:\n",
    "- `SequentialAMSHalfspace`\n",
    "- `SimultaneousAMSHyperplane`\n",
    "- `SequentialAMSHyperslab`\n",
    "\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from suppy.feasibility import SequentialAMSHyperslab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.5 0. ]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\t590r\\Documents\\GitHub\\suppy\\suppy\\utils\\_decorators.py:35: UserWarning: Array is not of type float32 or float64, converting to float64\n",
      "  warnings.warn(\"Array is not of type float32 or float64, converting to float64\")\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1, 1], [-1, 1], [1, 0], [0, 1]])\n",
    "lb = np.array([-2, -2, -3 / 2, -3 / 2])\n",
    "ub = -1 * lb\n",
    "seq_model = SequentialAMSHyperslab(A, lb, ub)\n",
    "x_0 = np.array([10,2])\n",
    "x_sol = seq_model.solve(x_0,3000)\n",
    "print(x_sol)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Furthermore, for hyperslab problems implementation for the ART3+ algorithm and ARM (Automatic relaxation method) can be found in `SequentialART3+` `SequentialARM`, respectively."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Combining Projections"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These projection objects can also be combined with the generalized implementations of `SequentialProjection`, `SimultaneousProjection`, `BlockIterativeProjection` and `StringAveragedProjection`.\n",
    "For example a linear model with $lb \\leq Ax \\leq ub$, that also wants to ensure that $x \\geq 0$ can be set up sequentially using an additional `BoxProjection` ($lb \\leq x \\leq ub$). Effectively, this approach approach performs a \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from suppy.projections import BoxProjection, SequentialProjection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_pos = BoxProjection(0, np.inf)\n",
    "full_model = SequentialProjection([seq_model, x_pos])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0. 0.]\n"
     ]
    }
   ],
   "source": [
    "x_0 = np.array([-3,-3])\n",
    "x_sol = full_model.solve(x_0,3000)\n",
    "print(x_sol)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "suppy",
   "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.11.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
