{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "353f2469-7c61-4c7e-b968-9551e1056ad2",
   "metadata": {},
   "source": [
    "## Generate random plane and point"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7a03b451-28ba-4f42-adb6-1c9b2486d64a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import ProjectiveGeometry23.utils as pgu\n",
    "\n",
    "np.set_printoptions(suppress=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "9f0ff326-31c3-439f-9bd5-60fe7b380d48",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.58925621,  0.61591353,  0.35038224, 10.        ])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "E = np.random.rand(4)\n",
    "E[3] = 10\n",
    "E"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3034c45d-08fc-43c9-b533-d1a5447b0977",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.63938635,  0.6683115 ,  0.38019052, 10.85073587])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "E = pgu.hessianNormalForm(E)\n",
    "E"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "1036e11d-f76c-4b27-816e-34f6f3d7ad45",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.11389707, 0.912803  , 4.8456686 , 1.        ])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = np.random.rand(4) * 10\n",
    "X[3] = 1\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9205a9ac-4162-494a-9ddf-1436ea0341f8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.63938635, 0.6683115 , 0.38019052, 0.        ])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# infinite point in direction of normal\n",
    "X_orthE = E\n",
    "X_orthE[3] = 0\n",
    "X_orthE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0a374eda-6ffb-4db3-85aa-a6d10c49cca1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from ProjectiveGeometry23.pluecker import join_points, meet, direction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "bc2b273e-302c-42fe-a73a-618b3e46819b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.16079644],\n",
       "       [-2.67476127],\n",
       "       [-0.63938635],\n",
       "       [-2.89137701],\n",
       "       [-0.6683115 ],\n",
       "       [-0.38019052]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L = join_points(X, X_orthE)\n",
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "83732039-657a-408b-a7c6-41a9bf0bccfe",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.63938635],\n",
       "       [0.6683115 ],\n",
       "       [0.38019052]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "direction(L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "0bdd9715-9a42-4aa6-9bef-23fee9a9104f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.90945676],\n",
       "       [ 1.20208517],\n",
       "       [-3.64254636],\n",
       "       [-1.        ]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_projected = meet(L, E)\n",
    "X_projected"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "dee5136b-94a5-4930-a679-e139c5265a32",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.90945676],\n",
       "       [-1.20208517],\n",
       "       [ 3.64254636]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pgu.dehomogenize(X_projected)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ad126c9-0427-4fd0-862a-57db59db6695",
   "metadata": {},
   "source": [
    "## And now the same with plain numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "bf04dcd2-b315-4c56-924e-106e193bb95f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c77ba50a-85bb-419b-8f83-3b41aa7d44b4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 1])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array([0,0,0,1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "ecad1bf6-aac3-4d50-ad1a-76747f2c2e80",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0],\n",
       "       [0],\n",
       "       [0],\n",
       "       [1]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "origin = np.array([[0],[0],[0],[1]])\n",
    "origin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "d92a68c8-9ea1-41e5-bfa4-913aada3001a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 1])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array([0,0,0,1]).transpose()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "ee341959-7669-4fab-a473-2e0876a331a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0],\n",
       "       [0],\n",
       "       [0],\n",
       "       [1]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.array([0,0,0,1]).reshape((4,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "a50d86c3-5bd4-4101-a75b-f507a1cf2369",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.63938635],\n",
       "       [0.6683115 ],\n",
       "       [0.38019052],\n",
       "       [0.        ]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "E = E.reshape((4,1))\n",
    "E"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "0d6bcd39-9d17-4909-97cc-dfc8eccf7e34",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1.11389707],\n",
       "       [0.912803  ],\n",
       "       [4.8456686 ],\n",
       "       [1.        ]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = X.reshape((4,1))\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "549110b9-8f40-4dfa-bb2a-3eb21b667a03",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.63938635],\n",
       "       [0.6683115 ],\n",
       "       [0.38019052],\n",
       "       [0.        ]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_orthE = X_orthE.reshape((4,1))\n",
    "X_orthE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "226d1334-0f9d-4f02-9087-0edeb04107bf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.71221059, 0.74443022, 0.4234931 , 0.        ],\n",
       "       [0.58363378, 0.61003675, 0.34703905, 0.        ],\n",
       "       [3.09825437, 3.23841606, 1.84227725, 0.        ],\n",
       "       [0.63938635, 0.6683115 , 0.38019052, 0.        ]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X @ X_orthE.transpose()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "0323447d-9c5e-47ce-8059-4f2007fe1b19",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.        , -0.16079644,  2.67476127,  0.63938635],\n",
       "       [ 0.16079644,  0.        ,  2.89137701,  0.6683115 ],\n",
       "       [-2.67476127, -2.89137701,  0.        ,  0.38019052],\n",
       "       [-0.63938635, -0.6683115 , -0.38019052,  0.        ]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Lx_orth = X_orthE @ X.transpose() - X @ X_orthE.transpose()\n",
    "Lx_orth"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "7013cebe-d2c7-45b1-a94e-465baa87f47f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.90945676],\n",
       "       [-1.20208517],\n",
       "       [ 3.64254636],\n",
       "       [ 1.        ]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_projected = Lx_orth @ E\n",
    "X_projected / X_projected[3]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f017ec17-c89d-47fa-9334-197fe941b5ab",
   "metadata": {},
   "source": [
    "Let's re-write it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d7c1bbb3-3de2-4a0b-92c4-1d1a227c74a0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.90945676],\n",
       "       [-1.20208517],\n",
       "       [ 3.64254636],\n",
       "       [ 1.        ]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_projected = X_orthE @ X.transpose() @ E - X @ X_orthE.transpose() @ E\n",
    "X_projected / X_projected[3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "0696096a-5087-4b5e-9a6f-6edd53249b92",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3.16452459]]  is dot product!\n",
      "[[3.16452459]]  is eqal.\n",
      "so\n",
      "[[2.02335383]\n",
      " [2.11488818]\n",
      " [1.20312224]\n",
      " [0.        ]]\n",
      "is also equal:\n",
      "[[2.02335383]\n",
      " [2.11488818]\n",
      " [1.20312224]\n",
      " [0.        ]]\n"
     ]
    }
   ],
   "source": [
    "print(X.transpose() @ E, \" is dot product!\")\n",
    "print(E.transpose() @ X, \" is eqal.\")\n",
    "print(\"so\")\n",
    "print(X_orthE @ X.transpose() @ E)\n",
    "print(\"is also equal:\")\n",
    "print((X_orthE @ E.transpose()) @ X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "ec25d959-ef1c-4127-b34b-e63b03ef7187",
   "metadata": {},
   "outputs": [],
   "source": [
    "M = X_orthE @ E.T - X_orthE.T @ E * np.eye(4)\n",
    "\n",
    "X_projected = M @ X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b698911a-cc01-40d2-8ed4-4ee8a202517f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
