|
- {
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Framework Improvements"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {},
- "outputs": [],
- "source": [
- "load(\"../framework/instance_gen.sage\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {},
- "outputs": [],
- "source": [
- "PACKAGES_FOLDER = '/home/sage/Nextcloud/Apprentissage/Telecom ParisTech/MPRI/Stages/CryptoExperts/python-packages'\n",
- "import sys\n",
- "if PACKAGES_FOLDER not in sys.path:\n",
- " sys.path += [PACKAGES_FOLDER]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dimension reduction"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 130,
- "metadata": {},
- "outputs": [],
- "source": [
- "n = 70\n",
- "m = n\n",
- "q = 3301\n",
- "D_s = build_centered_binomial_law(40)\n",
- "D_e = build_centered_binomial_law(40)\n",
- "d = m + n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 131,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
- "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
- "_ = dbdd.estimate_attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 132,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[ -3 8 -2 0 6 7 7 4 3 -3 5 -6 12 -6 -1 -2 -2 -1 0 -9 3 3 6 1 9 -2 -4 8 2 -3 -5 0 -8 7 -1 3 1 0 7 -1 0 4 -5 -4 5 -8 -1 5 1 3 0 2 -1 4 4 1 5 7 -2 -1 2 -5 10 -2 -4 -7 8 1 11 -1 -6 2 8 1 3 3 -1 5 -3 -6 -3 5 3 0 1 1 -3 -5 9 -1 -6 -2 4 -5 0 1 6 -2 -5 -1 -10 1 1 3 0 6 5 2 -3 6 -1 2 3 -3 -2 -2 4 2 0 8 -1 3 -1 7 -7 9 5 1 -3 -6 8 1 -3 -3 10 -2 -2 3 3 -1 1]\n"
- ]
- }
- ],
- "source": [
- "print(dbdd.u_original)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 133,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate perfect hint \u001b[0m \u001b[3;32m \t Worthy hint ! \u001b[0m \u001b[1;33m dim=140, δ=1.01247621, β=42.87 \u001b[0m\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 133,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v = canonical_vec(n+m, 2)\n",
- "dbdd.integrate_perfect_hint(v, dbdd.leak(v))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 57,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "No error in implementation: True True\n"
- ]
- }
- ],
- "source": [
- "V = concatenate(v, -dbdd.leak(v))\n",
- "gamma, data = build_standard_substitution_matrix(V, output_data=True)\n",
- "print('No error in implementation:', data['normalization_matrix'] == (gamma.T * gamma).inverse(), data['det'] == (gamma.T * gamma).det())"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 58,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate perfect hint \u001b[0m \u001b[0m \u001b[0m\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 58,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v = canonical_vec(n+m, 0) + canonical_vec(n+m,1)\n",
- "dbdd.integrate_perfect_hint(v, dbdd.leak(v))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 59,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Dimension Basis = (141, 139)\n"
- ]
- }
- ],
- "source": [
- "print(f'Dimension Basis = {dbdd.D.dimensions()}')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 60,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Running the Attack \u001b[0m\n",
- "Running BKZ-39 \u001b[0m [0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[1;37;42m Success ! \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "beta, solution = dbdd.attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 129,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[0 0 0 0]\n",
- "[0 0 0 0]"
- ]
- },
- "execution_count": 129,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "zero_matrix(2,4)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 108,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[ 6 -4 4 -4 4 -5 0 -4 14 3 -4 3 2 6 4 -1 -1 6 0 -7 -3 -9 -5 6 -1 -1 -3 -9 -4 2 2 8 0 -2 6 7 0 4 0 -4 3 3 2 -3 -2 -3 1 0 -2 2 -3 0 1 4 -3 -4 1 8 4 -5 -5 -2 -3 8 3 -4 -2 -1 1 1 3 -1 4 -12 4 -6 5 1 13 6 2 2 4 -7 -6 1 5 4 0 -1 -1 1 -3 5 -1 -2 -4 -2 3 -2 -5 4 -4 -3 6 3 2 -2 -4 -2 4 -5 -1 -1 3 -3 6 1 10 2 1 1 -3 -2 12 3 -3 5 1 0 1 2 4 -6 -1 -5 7 5 1 -7 1]\n"
- ]
- }
- ],
- "source": [
- "print(solution)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "scrolled": true
- },
- "outputs": [],
- "source": [
- "print(dbdd.Gamma)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Integration of the $q$-modular hints"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 229,
- "metadata": {},
- "outputs": [],
- "source": [
- "load(\"../framework/instance_gen.sage\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 230,
- "metadata": {},
- "outputs": [],
- "source": [
- "n = 70\n",
- "m = n\n",
- "q = 3301\n",
- "D_s = build_centered_binomial_law(40)\n",
- "D_e = build_centered_binomial_law(40)\n",
- "d = m + n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 231,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
- "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
- "_ = dbdd.estimate_attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 232,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[ 4 -4 2 -4 5 -2 3 -4 1 -9 4 -2 -5 2 11 0 -3 5 1 2 -1 2 -1 6 -5 -5 -6 6 -1 2 -5 -2 -3 -4 4 0 4 -2 2 -1 -3 -2 -4 6 -4 1 1 1 1 0 11 0 2 9 -2 7 -4 5 -1 0 -2 -3 0 -4 6 -4 -1 -1 4 7 1 -5 -3 -4 5 -3 1 2 6 -1 -6 7 7 3 4 -2 -1 2 2 -4 6 0 2 1 -7 5 4 12 -3 -2 3 -3 6 -6 -4 -8 0 3 -2 -4 -1 1 1 -3 -2 -7 -2 -4 4 5 2 7 -3 3 10 -4 -4 -3 2 -1 0 -6 -1 -4 6 9 0 -7 -4 2 1]\n"
- ]
- }
- ],
- "source": [
- "print(dbdd.u_original)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 233,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(567.1386512297237, 419.40251829755783, 357.43739208094473)"
- ]
- },
- "execution_count": 233,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dbdd.volumes()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 234,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate q modular hint \u001b[0m \u001b[0m \u001b[0m\n",
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=140 \t δ=1.012476 \t β=42.87 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "v = vec(identity_matrix(n+m)[2])\n",
- "dbdd.integrate_q_modular_hint(v, dbdd.leak(v)-q, q, estimate=False)\n",
- "_ = dbdd.estimate_attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 235,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate q modular hint \u001b[0m \u001b[0m \u001b[0m\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 235,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "v = vec(identity_matrix(n+m)[3])\n",
- "dbdd.integrate_q_modular_hint(v, dbdd.leak(v)-q, q, estimate=False)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 236,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=139 \t δ=1.012658 \t β=40.28 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "_ = dbdd.estimate_attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 237,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(567.1386509034968, 413.41105375044987, 360.4331240282719)"
- ]
- },
- "execution_count": 237,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dbdd.volumes()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 238,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Running the Attack \u001b[0m\n",
- "Running BKZ-35 \u001b[0m [0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[1;37;42m Success ! \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "beta, solution = dbdd.attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 307,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(-86, 29)"
- ]
- },
- "execution_count": 307,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Pi = matrix([[2, -5]])\n",
- "D = matrix([[1,0],[9,0]])\n",
- "(Pi*D*Pi.T).det(), (Pi*Pi.T).det()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 289,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "141 x 140 dense matrix over Rational Field (use the '.str()' method to see the entries)"
- ]
- },
- "execution_count": 289,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dbdd.Gamma.T.gram_schmidt()[0].T"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 287,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on built-in function gram_schmidt:\n",
- "\n",
- "gram_schmidt(...) method of sage.matrix.matrix_rational_dense.Matrix_rational_dense instance\n",
- " Matrix.gram_schmidt(self, orthonormal=False)\n",
- " File: sage/matrix/matrix2.pyx (starting at line 9511)\n",
- " \n",
- " Performs Gram-Schmidt orthogonalization on the rows of the matrix,\n",
- " returning a new matrix and a matrix accomplishing the transformation.\n",
- " \n",
- " INPUT:\n",
- " \n",
- " - ``self`` - a matrix whose rows are to be orthogonalized.\n",
- " - ``orthonormal`` - default: ``False`` - if ``True`` the\n",
- " returned orthogonal vectors are unit vectors. This keyword\n",
- " is ignored if the matrix is over ``RDF`` or ``CDF`` and the\n",
- " results are always orthonormal.\n",
- " \n",
- " OUTPUT:\n",
- " \n",
- " A pair of matrices, ``G`` and ``M`` such that if ``A``\n",
- " represents ``self``, where the parenthetical properties occur\n",
- " when ``orthonormal = True``:\n",
- " \n",
- " - ``A = M*G``\n",
- " - The rows of ``G`` are an orthogonal (resp. orthonormal)\n",
- " set of vectors.\n",
- " - ``G`` times the conjugate-transpose of ``G`` is a diagonal\n",
- " (resp. identity) matrix.\n",
- " - The row space of ``G`` equals the row space of ``A``.\n",
- " - ``M`` is a full-rank matrix with zeros above the diagonal.\n",
- " \n",
- " For exact rings, any zero vectors produced (when the original\n",
- " vectors are linearly dependent) are not output, thus the\n",
- " orthonormal set is linearly independent, and thus a basis for the\n",
- " row space of the original matrix.\n",
- " \n",
- " Any notion of a Gram-Schmidt procedure requires that the base\n",
- " ring of the matrix has a fraction field implemented. In order\n",
- " to arrive at an orthonormal set, it must be possible to construct\n",
- " square roots of the elements of the base field. In Sage, your\n",
- " best option is the field of algebraic numbers, ``QQbar``, which\n",
- " properly contains the rationals and number fields.\n",
- " \n",
- " If you have an approximate numerical matrix, then this routine\n",
- " requires that your base field be the real and complex\n",
- " double-precision floating point numbers, ``RDF`` and ``CDF``.\n",
- " In this case, the matrix is treated as having full rank, as no\n",
- " attempt is made to recognize linear dependence with approximate\n",
- " calculations.\n",
- " \n",
- " EXAMPLES:\n",
- " \n",
- " Inexact Rings, Numerical Matrices:\n",
- " \n",
- " First, the inexact rings, ``CDF`` and ``RDF``. ::\n",
- " \n",
- " sage: A = matrix(CDF, [[ 0.6454 + 0.7491*I, -0.8662 + 0.1489*I, 0.7656 - 0.00344*I],\n",
- " ....: [-0.2913 + 0.8057*I, 0.8321 + 0.8170*I, -0.6744 + 0.9248*I],\n",
- " ....: [ 0.2554 + 0.3517*I, -0.4454 - 0.1715*I, 0.8325 - 0.6282*I]])\n",
- " sage: G, M = A.gram_schmidt()\n",
- " sage: G.round(6) # random signs\n",
- " [-0.422243 - 0.490087*I 0.566698 - 0.097416*I -0.500882 + 0.002251*I]\n",
- " [-0.057002 - 0.495035*I -0.35059 - 0.625323*I 0.255514 - 0.415284*I]\n",
- " [ 0.394105 - 0.421778*I -0.392266 - 0.039345*I -0.352905 + 0.62195*I]\n",
- " sage: M.round(6) # random\n",
- " [ -1.528503 0.0 0.0]\n",
- " [ 0.459974 - 0.40061*I -1.741233 0.0]\n",
- " [-0.934304 + 0.148868*I 0.54833 + 0.073202*I -0.550725]\n",
- " sage: (A - M*G).zero_at(10^-12)\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " sage: (G*G.conjugate_transpose()) # random\n",
- " [0.9999999999999999 0.0 0.0]\n",
- " [ 0.0 0.9999999999999997 0.0]\n",
- " [ 0.0 0.0 1.0]\n",
- " \n",
- " A rectangular matrix. Note that the ``orthonormal`` keyword\n",
- " is ignored in these cases. ::\n",
- " \n",
- " sage: A = matrix(RDF, [[-0.978325, -0.751994, 0.925305, -0.200512, 0.420458],\n",
- " ....: [-0.474877, -0.983403, 0.089836, 0.132218, 0.672965]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
- " sage: G.round(6).zero_at(10^-6)\n",
- " [-0.607223 -0.466745 0.574315 -0.124453 0.260968]\n",
- " [ 0.123203 -0.617909 -0.530578 0.289773 0.487368]\n",
- " sage: M.round(6).zero_at(10^-6)\n",
- " [1.611147 0.0]\n",
- " [0.958116 0.867778]\n",
- " sage: (A-M*G).zero_at(10^-12)\n",
- " [0.0 0.0 0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0 0.0 0.0]\n",
- " sage: (G*G.transpose()).round(6).zero_at(10^-6)\n",
- " [1.0 0.0]\n",
- " [0.0 1.0]\n",
- " \n",
- " Even though a set of vectors may be linearly dependent, no effort\n",
- " is made to decide when a zero vector is really the result of a\n",
- " relation of linear dependence. So in this regard, input matrices\n",
- " are treated as being of full rank. Try one of the base rings that\n",
- " provide exact results if you need exact results. ::\n",
- " \n",
- " sage: entries = [[1,1,2], [2,1,3], [3,1,4]]\n",
- " sage: A = matrix(QQ, entries)\n",
- " sage: A.rank()\n",
- " 2\n",
- " sage: B = matrix(RDF, entries)\n",
- " sage: G, M = B.gram_schmidt()\n",
- " sage: G.round(6) # random signs\n",
- " [-0.408248 -0.408248 -0.816497]\n",
- " [ 0.707107 -0.707107 -0.0]\n",
- " [ -0.57735 -0.57735 0.57735]\n",
- " sage: M.round(10) # random\n",
- " [-2.4494897428 0.0 0.0]\n",
- " [-3.6742346142 0.7071067812 0.0]\n",
- " [-4.8989794856 1.4142135624 0.0]\n",
- " sage: (A - M*G).zero_at(1e-14)\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " sage: (G*G.transpose()) # abs tol 1e-14\n",
- " [0.9999999999999997 0.0 0.0]\n",
- " [ 0.0 0.9999999999999998 0.0]\n",
- " [ 0.0 0.0 1.0]\n",
- " \n",
- " Exact Rings, Orthonormalization:\n",
- " \n",
- " To scale a vector to unit length requires taking\n",
- " a square root, which often takes us outside the base ring.\n",
- " For the integers and the rationals, the field of algebraic numbers\n",
- " (``QQbar``) is big enough to contain what we need, but the price\n",
- " is that the computations are very slow, hence mostly of value\n",
- " for small cases or instruction. Now we need to use the\n",
- " ``orthonormal`` keyword. ::\n",
- " \n",
- " sage: A = matrix(QQbar, [[6, -8, 1],\n",
- " ....: [4, 1, 3],\n",
- " ....: [6, 3, 3],\n",
- " ....: [7, 1, -5],\n",
- " ....: [7, -3, 5]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: G\n",
- " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
- " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
- " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
- " sage: M\n",
- " [ 10.04987562112089? 0 0]\n",
- " [ 1.890570661398980? 4.735582601355131? 0]\n",
- " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
- " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
- " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
- " sage: M*G-A\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " sage: (G*G.transpose()-identity_matrix(3)).norm() < 10^-10\n",
- " True\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " After :trac:`14047`, the matrix can also be over the algebraic reals\n",
- " ``AA``::\n",
- " \n",
- " sage: A = matrix(AA, [[6, -8, 1],\n",
- " ....: [4, 1, 3],\n",
- " ....: [6, 3, 3],\n",
- " ....: [7, 1, -5],\n",
- " ....: [7, -3, 5]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: G\n",
- " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
- " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
- " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
- " sage: M\n",
- " [ 10.04987562112089? 0 0]\n",
- " [ 1.890570661398980? 4.735582601355131? 0]\n",
- " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
- " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
- " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
- " \n",
- " Starting with complex numbers with rational real and imaginary parts.\n",
- " Note the use of the conjugate-transpose when checking the\n",
- " orthonormality. ::\n",
- " \n",
- " sage: A = matrix(QQbar, [[ -2, -I - 1, 4*I + 2, -1],\n",
- " ....: [-4*I, -2*I + 17, 0, 9*I + 1],\n",
- " ....: [ 1, -2*I - 6, -I + 11, -5*I + 1]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: (M*G-A).norm() < 10^-10\n",
- " True\n",
- " sage: id3 = G*G.conjugate().transpose()\n",
- " sage: (id3 - identity_matrix(3)).norm() < 10^-10\n",
- " True\n",
- " sage: G.row_space() == A.row_space() # long time\n",
- " True\n",
- " \n",
- " A square matrix with small rank. The zero vectors produced as a\n",
- " result of linear dependence get eliminated, so the rows of ``G``\n",
- " are a basis for the row space of ``A``. ::\n",
- " \n",
- " sage: A = matrix(QQbar, [[2, -6, 3, 8],\n",
- " ....: [1, -3, 2, 5],\n",
- " ....: [0, 0, 2, 4],\n",
- " ....: [2, -6, 3, 8]])\n",
- " sage: A.change_ring(QQ).rank()\n",
- " 2\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: G\n",
- " [ 0.1881441736767195? -0.5644325210301583? 0.2822162605150792? 0.7525766947068779?]\n",
- " [-0.2502818123591464? 0.750845437077439? 0.3688363550555841? 0.4873908977520218?]\n",
- " sage: M\n",
- " [10.630145812734649? 0]\n",
- " [ 6.208757731331742? 0.6718090752798139?]\n",
- " [ 3.574739299857670? 2.687236301119256?]\n",
- " [10.630145812734649? 0]\n",
- " sage: M*G-A\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " sage: (G*G.transpose()-identity_matrix(2)).norm() < 10^-10\n",
- " True\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " Exact Rings, Orthogonalization:\n",
- " \n",
- " If we forego scaling orthogonal vectors to unit vectors, we\n",
- " can apply Gram-Schmidt to a much greater variety of rings.\n",
- " Use the ``orthonormal=False`` keyword (or assume it as the default).\n",
- " Note that now the orthogonality check creates a diagonal matrix\n",
- " whose diagonal entries are the squares of the lengths of the\n",
- " vectors.\n",
- " \n",
- " First, in the rationals, without involving ``QQbar``. ::\n",
- " \n",
- " sage: A = matrix(QQ, [[-1, 3, 2, 2],\n",
- " ....: [-1, 0, -1, 0],\n",
- " ....: [-1, -2, -3, -1],\n",
- " ....: [ 1, 1, 2, 0]])\n",
- " sage: A.rank()\n",
- " 3\n",
- " sage: G, M = A.gram_schmidt()\n",
- " sage: G\n",
- " [ -1 3 2 2]\n",
- " [-19/18 1/6 -8/9 1/9]\n",
- " [ 2/35 -4/35 -2/35 9/35]\n",
- " sage: M\n",
- " [ 1 0 0]\n",
- " [ -1/18 1 0]\n",
- " [-13/18 59/35 1]\n",
- " [ 1/3 -48/35 -2]\n",
- " sage: M*G-A\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " sage: G*G.transpose()\n",
- " [ 18 0 0]\n",
- " [ 0 35/18 0]\n",
- " [ 0 0 3/35]\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " A complex subfield of the complex numbers. ::\n",
- " \n",
- " sage: C.<z> = CyclotomicField(5)\n",
- " sage: A = matrix(C, [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1],\n",
- " ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z],\n",
- " ....: [-1/2*z^3 - 2*z^2 + z + 1, -z^3 + z - 2, -2*z^3 + 1/2*z^2, 2*z^2 - z + 2]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
- " sage: G\n",
- " [ -z^3 - 2*z -z^3 - 1 2*z^3 - 2*z^2 + 2*z 1]\n",
- " [ 155/139*z^3 - 161/139*z^2 + 31/139*z + 13/139 -175/139*z^3 + 180/139*z^2 - 125/139*z - 142/139 230/139*z^3 + 124/139*z^2 + 6/139*z + 19/139 -14/139*z^3 + 92/139*z^2 - 6/139*z - 95/139]\n",
- " [-10359/19841*z^3 - 36739/39682*z^2 + 24961/39682*z - 11879/39682 -28209/39682*z^3 - 3671/19841*z^2 + 51549/39682*z - 38613/39682 -42769/39682*z^3 - 615/39682*z^2 - 1252/19841*z - 14392/19841 4895/19841*z^3 + 57885/39682*z^2 - 46094/19841*z + 65747/39682]\n",
- " sage: M\n",
- " [ 1 0 0]\n",
- " [ 14/139*z^3 + 47/139*z^2 + 145/139*z + 95/139 1 0]\n",
- " [ -7/278*z^3 + 199/278*z^2 + 183/139*z + 175/278 -3785/39682*z^3 + 3346/19841*z^2 - 3990/19841*z + 2039/19841 1]\n",
- " sage: M*G - A\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " sage: G*G.conjugate().transpose()\n",
- " [ 15*z^3 + 15*z^2 + 28 0 0]\n",
- " [ 0 463/139*z^3 + 463/139*z^2 + 1971/139 0]\n",
- " [ 0 0 230983/19841*z^3 + 230983/19841*z^2 + 1003433/39682]\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " A slightly edited legacy example. ::\n",
- " \n",
- " sage: A = matrix(ZZ, 3, [-1, 2, 5, -11, 1, 1, 1, -1, -3]); A\n",
- " [ -1 2 5]\n",
- " [-11 1 1]\n",
- " [ 1 -1 -3]\n",
- " sage: G, mu = A.gram_schmidt()\n",
- " sage: G\n",
- " [ -1 2 5]\n",
- " [ -52/5 -1/5 -2]\n",
- " [ 2/187 36/187 -14/187]\n",
- " sage: mu\n",
- " [ 1 0 0]\n",
- " [ 3/5 1 0]\n",
- " [ -3/5 -7/187 1]\n",
- " sage: G.row(0) * G.row(1)\n",
- " 0\n",
- " sage: G.row(0) * G.row(2)\n",
- " 0\n",
- " sage: G.row(1) * G.row(2)\n",
- " 0\n",
- " \n",
- " The relation between mu and A is as follows. ::\n",
- " \n",
- " sage: mu*G == A\n",
- " True\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(dbdd.Gamma.gram_schmidt)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 277,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "<class 'sage.rings.rational.Rational'>\n",
- "<class 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> <class 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'>\n"
- ]
- }
- ],
- "source": [
- "solution = dbdd.reduced_solution \n",
- "\n",
- "for instruc_type, Gamma, data in dbdd._restoration_instructions[::-1]:\n",
- " solution = solution * Gamma.T\n",
- " if instruc_type == SUBSTITUTION:\n",
- " pass\n",
- " elif instruc_type == QMODULUS_SUBSTITUTION:\n",
- " print(type(solution[0].inner_product(data['v'][0])))\n",
- " print(type(data['v']), type(data['w']))\n",
- " solution += data['w'] * round(solution[0].inner_product(data['v'][0])/data['q'])\n",
- " else:\n",
- " solution += data['w'] * data['func'](solution)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 265,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "140 x 140 dense matrix over Rational Field (use the '.str()' method to see the entries)"
- ]
- },
- "execution_count": 265,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dbdd.B"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 116,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate q modular hint \u001b[0m "
- ]
- },
- {
- "ename": "TypeError",
- "evalue": "unsupported operand parent(s) for *: 'Full MatrixSpace of 1 by 140 dense matrices over Rational Field' and 'Full MatrixSpace of 141 by 1 dense matrices over Integer Ring'",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-116-a41d5e3e2a5b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0midentity_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0midentity_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\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[0;32m----> 2\u001b[0;31m \u001b[0mdbdd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mintegrate_q_modular_hint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdbdd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mleak\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mq\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mw\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mq\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mv\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 3\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdbdd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestimate_attack\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[0;32m<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mintegrate_q_modular_hint\u001b[0;34m(self, v, l, q, w)\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/structure/element.pyx\u001b[0m in \u001b[0;36msage.structure.element.Matrix.__mul__ (build/cythonized/sage/structure/element.c:22674)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 3693\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3694\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mBOTH_ARE_ELEMENT\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcl\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[0;32m-> 3695\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcoercion_model\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbin_op\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mleft\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mright\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmul\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 3696\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3697\u001b[0m \u001b[0mcdef\u001b[0m \u001b[0mlong\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/structure/coerce.pyx\u001b[0m in \u001b[0;36msage.structure.coerce.CoercionModel.bin_op (build/cythonized/sage/structure/coerce.c:11180)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1253\u001b[0m \u001b[0;31m# We should really include the underlying error.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1254\u001b[0m \u001b[0;31m# This causes so much headache.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1255\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mbin_op_exception\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\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 1256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1257\u001b[0m \u001b[0mcpdef\u001b[0m \u001b[0mcanonical_coercion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\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[0;31mTypeError\u001b[0m: unsupported operand parent(s) for *: 'Full MatrixSpace of 1 by 140 dense matrices over Rational Field' and 'Full MatrixSpace of 141 by 1 dense matrices over Integer Ring'"
- ]
- }
- ],
- "source": [
- "v = vec(identity_matrix(n+m)[3]+identity_matrix(n+m)[4])\n",
- "dbdd.integrate_q_modular_hint(v, dbdd.leak(v)+q, q, w=q*v)\n",
- "_ = dbdd.estimate_attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate q modular hint \u001b[0m "
- ]
- },
- {
- "ename": "AttributeError",
- "evalue": "'DBDD' object has no attribute 'gamma'",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-5-b64948fbe0f2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0midentity_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mcoeff\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[1;32m 3\u001b[0m \u001b[0ml\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdbdd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mu_original\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mcoeff\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mq\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mdbdd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mintegrate_q_modular_hint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mq\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<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mintegrate_q_modular_hint\u001b[0;34m(self, v, l, q, w)\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mget_reduced_vector\u001b[0;34m(self, V)\u001b[0m\n",
- "\u001b[0;31mAttributeError\u001b[0m: 'DBDD' object has no attribute 'gamma'"
- ]
- }
- ],
- "source": [
- "coeff = 2\n",
- "v = vec(identity_matrix(n+m)[coeff])\n",
- "l = dbdd.u_original[0,coeff] + 100*q\n",
- "dbdd.integrate_q_modular_hint(v, l, q)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 244,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[ -3 0 2 -4 5 2 1 -1 -1 -1 1 2 -1 1 0 4 5 -10 2 -1 -10 7 9 5 -2 1 6 2 4 -3 0 -1 -6 0 4 -3 -2 3 0 0 -4 -2 1 -5 3 1 4 -3 -2 -2 12 -19 2 -4 1 1 0 2 -4 7 2 -3 -3 -2 -4 1 -3 5 -9 0 0 -1 5 1 -1 8 -2 6 5 -4 1 -6 -5 -4 0 11 0 -3 1 4 1 -4 -3 2 1 10 -5 0 2 2 -2 2 0 6 7 -3 0 0 4 -4 -6 -1 1 5 3 0 0 4 5 -10 5 4 0 -2 5 -1 -8 4 0 4 -1 1 -7 -1 1 1 -3 -3 1 -2 -1]\n"
- ]
- }
- ],
- "source": [
- "print(solution)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 233,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'[ 20 64 10 34 -86 -80 -130 -75 -24 87 42 53 31 -53 60 23 -52 -17 -78 -17 67 -46 -81 164 -161 10 -104 137 -37 -132 -146 -116 1 -173 127 76 101 30 69 42 61 12 34 47 82 -97 31 -31 -116 -232 5 -70 17 46 -50 89 -80 40 -35 -12 49 -134 -25 -8 -56 -152 38 93 -17 -14 58 -28 67 60 -76 149 -51 102 -85 -85 -58 -33 -118 18 117 104 37 46 137 35 -34 -70 68 -171 -116 -25 34 -48 34 0 9 -66 65 -14 -79 -112 -60 -80 105 -152 -100 2 -92 -135 -110 -64 -73 131 66 35 142 -4 -12 -23 -60 -64 -57 54 -61 50 -107 -91 99 12 -15 55 58 28 -15 30 2]'"
- ]
- },
- "execution_count": 233,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "solution = solution.apply_map(lambda x: dbdd.center(x,dbdd.q))\n",
- "solution.str()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 61,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "5 <class 'sage.rings.rational.Rational'> <class 'sage.matrix.matrix_rational_dense.Matrix_rational_dense'>\n",
- "6\n",
- "3\n"
- ]
- }
- ],
- "source": [
- "V_ = V\n",
- "_, pivot = V_.nonzero_positions()[0]\n",
- "dim = dbdd.D.ncols()\n",
- "\n",
- "V1 = V_[0,:pivot] / V_[0,pivot]\n",
- "V2 = V_[0,pivot+1:] / V_[0,pivot]\n",
- "\n",
- "if data is not None:\n",
- " norm2 = 1 + scal(V1*V1.T) + scal(V2*V2.T)\n",
- " print(5, type(norm2), type(V1.T*V1))\n",
- " normalization_matrix = zero_matrix(QQ, dim-1,dim-1)\n",
- " normalization_matrix[:pivot,:pivot] = identity_matrix(pivot) - V1.T*V1 / norm2\n",
- " print(6)\n",
- " normalization_matrix[pivot:,pivot:] = identity_matrix(dim-pivot-1) - V2.T*V2 / norm2\n",
- " print(3)\n",
- " normalization_matrix[:pivot,pivot:] = - V1.T*V2 / norm2\n",
- " normalization_matrix[pivot:,:pivot] = - V2.T*V1 / norm2\n",
- "\n",
- " data['det'] = norm2\n",
- " data['normalization_matrix'] = normalization_matrix"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 55,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[1 0]\n",
- "[0 1]"
- ]
- },
- "execution_count": 55,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "identity_matrix(pivot) - V1.T*V1 / norm2"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 57,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "138 x 138 dense matrix over Rational Field (use the '.str()' method to see the entries)"
- ]
- },
- "execution_count": 57,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "identity_matrix(dim-pivot-1) - V2.T*V2 / norm2"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 58,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "140 x 140 dense matrix over Integer Ring (use the '.str()' method to see the entries)"
- ]
- },
- "execution_count": 58,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "normalization_matrix"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 201,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on method map_item in module sage.categories.modules_with_basis:\n",
- "\n",
- "map_item(f) method of sage.matrix.matrix_integer_dense.Matrix_integer_dense instance\n",
- " Mapping a function on items.\n",
- " \n",
- " INPUT:\n",
- " \n",
- " - ``f`` -- a function mapping pairs ``(index, coeff)`` to\n",
- " other such pairs\n",
- " \n",
- " Return a new element of ``self.parent()`` obtained by\n",
- " applying the function `f` to all items ``(index, coeff)`` of\n",
- " ``self``.\n",
- " \n",
- " EXAMPLES::\n",
- " \n",
- " sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1])\n",
- " sage: x = B.an_element(); x\n",
- " 2*B[-1] + 2*B[0] + 3*B[1]\n",
- " sage: x.map_item(lambda i, c: (-i, 2*c))\n",
- " 6*B[-1] + 4*B[0] + 4*B[1]\n",
- " \n",
- " ``f`` needs not be injective::\n",
- " \n",
- " sage: x.map_item(lambda i, c: (1, 2*c))\n",
- " 14*B[1]\n",
- " \n",
- " sage: s = SymmetricFunctions(QQ).schur()\n",
- " sage: f = lambda m,c: (m.conjugate(), 2*c)\n",
- " sage: a = s([2,1]) + s([1,1,1])\n",
- " sage: a.map_item(f)\n",
- " 2*s[2, 1] + 2*s[3]\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(V.map_item)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 226,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[1 1 0 0 0 0 0 0 0 0]"
- ]
- },
- "execution_count": 226,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "V[0,:10]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 227,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[6 6 5 5 5 5 5 5 5 5]"
- ]
- },
- "execution_count": 227,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "V[0,:10].apply_map(lambda x: x+5)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Forced dimension reduction"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "load(\"../framework/instance_gen.sage\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "n = 70\n",
- "m = n\n",
- "q = 3301\n",
- "D_s = build_centered_binomial_law(40)\n",
- "D_e = build_centered_binomial_law(40)\n",
- "d = m + n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
- "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
- "_ = dbdd.estimate_attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "141 x 141 dense matrix over Integer Ring (use the '.str()' method to see the entries)"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dbdd.B"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {},
- "outputs": [],
- "source": [
- "I = identity_matrix(5)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {},
- "outputs": [],
- "source": [
- "I[2,2]=0"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "0"
- ]
- },
- "execution_count": 26,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "min([i for i in range(I.nrows()) if not I[i].is_zero()])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "I.nrows()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Measure the gain of time without LLL"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 91,
- "metadata": {},
- "outputs": [],
- "source": [
- "load(\"../framework/instance_gen.sage\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 92,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[3;34m Number of threads : 1 \u001b[0m\n",
- "\u001b[3;34m Number of Samples : 5 \u001b[0m\n",
- "\u001b[4;37m Validation tests \u001b[0m\n",
- "\n",
- " \n",
- " Perfect\n",
- "hints,\t real,\t pred_full, \t pred_light,\n",
- "LLL... (False)141\n",
- "Done.\n",
- "LLL... (True)Go... [None]\n",
- "[141->140]\n",
- "140\n",
- "Done.\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "Process Process-85:\n",
- "Traceback (most recent call last):\n",
- " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 297, in _bootstrap\n",
- " self.run()\n",
- " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 99, in run\n",
- " self._target(*self._args, **self._kwargs)\n",
- " File \"/home/sage/Nextcloud/Apprentissage/Telecom ParisTech/MPRI/Stages/CryptoExperts/python-packages/leaky_lwe_estimator/Sec5.2_validation/map_drop.py\", line 17, in ff\n",
- " r = f(i + 2**16 * trial, args)\n",
- " File \"<string>\", line 59, in one_experiment\n",
- " File \"<string>\", line 37, in decorated\n",
- " File \"<string>\", line 125, in decorated\n",
- " File \"<string>\", line 96, in integrate_perfect_hint\n",
- " File \"<string>\", line 102, in lattice_orthogonal_section\n",
- " File \"<string>\", line 55, in project_and_eliminate_dep\n",
- " File \"<string>\", line 20, in projection_matrix\n",
- " File \"sage/matrix/matrix_rational_dense.pyx\", line 730, in sage.matrix.matrix_rational_dense.Matrix_rational_dense.inverse (build/cythonized/sage/matrix/matrix_rational_dense.c:8696)\n",
- " return self._invert_flint()\n",
- " File \"sage/matrix/matrix_rational_dense.pyx\", line 633, in sage.matrix.matrix_rational_dense.Matrix_rational_dense._invert_flint (build/cythonized/sage/matrix/matrix_rational_dense.c:8428)\n",
- " raise ZeroDivisionError(\"input matrix must be nonsingular\")\n",
- "ZeroDivisionError: input matrix must be nonsingular\n"
- ]
- },
- {
- "ename": "KeyboardInterrupt",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-92-a0f7d996ff91>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'time_verifications.sage'\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/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/misc/persist.pyx\u001b[0m in \u001b[0;36msage.misc.persist.load (build/cythonized/sage/misc/persist.c:2538)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 142\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrepl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_loadable_filename\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\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[0;32m--> 144\u001b[0;31m \u001b[0msage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrepl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mglobals\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[1;32m 145\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/repl/load.py\u001b[0m in \u001b[0;36mload\u001b[0;34m(filename, globals, attach)\u001b[0m\n\u001b[1;32m 270\u001b[0m \u001b[0madd_attached_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfpath\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 271\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfpath\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 272\u001b[0;31m \u001b[0mexec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpreparse_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\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\"\\n\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mglobals\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 273\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mext\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'.spyx'\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mext\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'.pyx'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 274\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mattach\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvalidation_prediction\u001b[0;34m(N_tests, N_hints, T_hints)\u001b[0m\n",
- "\u001b[0;32m/home/sage/Nextcloud/Apprentissage/Telecom ParisTech/MPRI/Stages/CryptoExperts/python-packages/leaky_lwe_estimator/Sec5.2_validation/map_drop.py\u001b[0m in \u001b[0;36mmap_drop\u001b[0;34m(nb, threads, f, aargs, max_drop)\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[0mret\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[1;32m 30\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mthreads\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnb\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mthreads\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[0;32m---> 31\u001b[0;31m \u001b[0mret\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mreturn_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# this is blocking\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 32\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mnb\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/queues.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, block, timeout)\u001b[0m\n\u001b[1;32m 92\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mblock\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 93\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_rlock\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 94\u001b[0;31m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv_bytes\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[1;32m 95\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrelease\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[1;32m 96\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[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/connection.py\u001b[0m in \u001b[0;36mrecv_bytes\u001b[0;34m(self, maxlength)\u001b[0m\n\u001b[1;32m 214\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmaxlength\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mmaxlength\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 215\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"negative maxlength\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 216\u001b[0;31m \u001b[0mbuf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv_bytes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmaxlength\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 217\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mbuf\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_bad_message_length\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[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/connection.py\u001b[0m in \u001b[0;36m_recv_bytes\u001b[0;34m(self, maxsize)\u001b[0m\n\u001b[1;32m 405\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 406\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_recv_bytes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmaxsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\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[0;32m--> 407\u001b[0;31m \u001b[0mbuf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\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 408\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstruct\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munpack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"!i\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbuf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetvalue\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[1;32m 409\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmaxsize\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0msize\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mmaxsize\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/connection.py\u001b[0m in \u001b[0;36m_recv\u001b[0;34m(self, size, read)\u001b[0m\n\u001b[1;32m 377\u001b[0m \u001b[0mremaining\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 378\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mremaining\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 379\u001b[0;31m \u001b[0mchunk\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremaining\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 380\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchunk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 381\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32msrc/cysignals/signals.pyx\u001b[0m in \u001b[0;36mcysignals.signals.python_check_interrupt\u001b[0;34m()\u001b[0m\n",
- "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
- ]
- }
- ],
- "source": [
- "load('time_verifications.sage')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 116,
- "metadata": {},
- "outputs": [],
- "source": [
- "help(dbdd.B.gram_schmidt)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 119,
- "metadata": {},
- "outputs": [],
- "source": [
- "M, G = dbdd.B.gram_schmidt()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [],
- "source": [
- "B = dbdd.B"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [],
- "source": [
- "def extend_into_basis(elt, B):\n",
- " dim = B.nrows()\n",
- " linear_combinaison = zero_matrix(RR, 1, 1+dim)\n",
- " \n",
- " rest = B[dim-1]\n",
- " for i in range(B.nrows()):\n",
- " print(i)\n",
- " v = elt if i==0 else B[i-1]\n",
- " alpha = -rest.inner_product(v)/v.norm()\n",
- " rest += v*alpha\n",
- " linear_combinaison[0,i] = alpha\n",
- " \n",
- " print(rest)\n",
- " return rest, linear_combinaison"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "0\n",
- "1\n",
- "2\n",
- "3\n",
- "4\n",
- "5\n",
- "6\n",
- "7\n",
- "8\n",
- "9\n",
- "10\n",
- "11\n",
- "12\n",
- "13\n",
- "14\n",
- "15\n",
- "16\n",
- "17\n",
- "18\n",
- "19\n",
- "20\n",
- "21\n",
- "22\n",
- "23\n",
- "24\n",
- "25\n",
- "26\n",
- "27\n",
- "28\n",
- "29\n",
- "30\n",
- "31\n",
- "32\n",
- "33\n",
- "34\n",
- "35\n",
- "36\n",
- "37\n",
- "38\n",
- "39\n",
- "40\n",
- "41\n",
- "42\n",
- "43\n",
- "44\n",
- "45\n",
- "46\n",
- "47\n",
- "48\n",
- "49\n",
- "50\n",
- "51\n",
- "52\n",
- "53\n",
- "54\n",
- "55\n",
- "56\n",
- "57\n",
- "58\n",
- "59\n",
- "60\n",
- "61\n",
- "62\n",
- "63\n",
- "64\n",
- "65\n",
- "66\n",
- "67\n",
- "68\n",
- "69\n",
- "70\n",
- "71\n",
- "72\n",
- "73\n",
- "74\n",
- "75\n",
- "76\n",
- "77\n",
- "78\n",
- "79\n",
- "80\n",
- "81\n",
- "82\n",
- "83\n",
- "84\n",
- "85\n",
- "86\n",
- "87\n",
- "88\n",
- "89\n",
- "90\n",
- "91\n",
- "92\n",
- "93\n"
- ]
- },
- {
- "ename": "KeyboardInterrupt",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-6-11ab203230c5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcombi\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mextend_into_basis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0midentity_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m141\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\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[0mdbdd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mB\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<ipython-input-5-0af744f5ae95>\u001b[0m in \u001b[0;36mextend_into_basis\u001b[0;34m(elt, B)\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0malpha\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0mrest\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minner_product\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnorm\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[1;32m 10\u001b[0m \u001b[0mrest\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0malpha\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mlinear_combinaison\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0malpha\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrest\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/matrix0.pyx\u001b[0m in \u001b[0;36msage.matrix.matrix0.Matrix.__setitem__ (build/cythonized/sage/matrix/matrix0.c:8832)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1427\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1428\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msingle_row\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0msingle_col\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mno_col_index\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1429\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_unsafe\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcol\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_coerce_element\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\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[1;32m 1430\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1431\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/matrix0.pyx\u001b[0m in \u001b[0;36msage.matrix.matrix0.Matrix._coerce_element (build/cythonized/sage/matrix/matrix0.c:10309)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1532\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mElement\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mElement\u001b[0m\u001b[0;34m>\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_base_ring\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1533\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1534\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_base_ring\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\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 1535\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1536\u001b[0m \u001b[0;31m###########################################################\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/structure/parent.pyx\u001b[0m in \u001b[0;36msage.structure.parent.Parent.__call__ (build/cythonized/sage/structure/parent.c:9218)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 898\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmor\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 899\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mno_extra_args\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 900\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mmor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\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 901\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 902\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_with_args\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/structure/coerce_maps.pyx\u001b[0m in \u001b[0;36msage.structure.coerce_maps.NamedConvertMap._call_ (build/cythonized/sage/structure/coerce_maps.c:5949)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Cannot coerce {} to {}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mC\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[1;32m 286\u001b[0m \u001b[0mcdef\u001b[0m \u001b[0mMap\u001b[0m \u001b[0mm\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 287\u001b[0;31m \u001b[0mcdef\u001b[0m \u001b[0mElement\u001b[0m \u001b[0me\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mC\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 288\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0me\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 289\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"BUG in coercion model: {} method of {} returned None\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmethod_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\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[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/symbolic/expression.pyx\u001b[0m in \u001b[0;36msage.symbolic.expression.Expression._mpfr_ (build/cythonized/sage/symbolic/expression.cpp:10328)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1307\u001b[0m \u001b[0;36m0.14112000805986722210074480281\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1308\u001b[0m \"\"\"\n\u001b[0;32m-> 1309\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_eval_self\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mR\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 1310\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1311\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_real_mpfi_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mR\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[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/symbolic/expression.pyx\u001b[0m in \u001b[0;36msage.symbolic.expression.Expression._eval_self (build/cythonized/sage/symbolic/expression.cpp:9623)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1217\u001b[0m \"\"\"\n\u001b[1;32m 1218\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1219\u001b[0;31m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_convert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m'parent'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mR\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[1;32m 1220\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mTypeError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1221\u001b[0m \u001b[0;31m# try the evaluation again with the complex field\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/symbolic/expression.pyx\u001b[0m in \u001b[0;36msage.symbolic.expression.Expression._convert (build/cythonized/sage/symbolic/expression.cpp:10212)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1286\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1287\u001b[0m \"\"\"\n\u001b[0;32m-> 1288\u001b[0;31m \u001b[0mcdef\u001b[0m \u001b[0mGEx\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_gobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mevalf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwds\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 1289\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mnew_Expression_from_GEx\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1290\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/rings/real_mpfr.pyx\u001b[0m in \u001b[0;36msage.rings.real_mpfr.RealNumber.__pow__ (build/cythonized/sage/rings/real_mpfr.c:27118)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4242\u001b[0m \u001b[0mrounding_mode\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0mRealField_class\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0mbase\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrnd\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4243\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbase\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_new\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[0;32m-> 4244\u001b[0;31m \u001b[0msig_on\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[1;32m 4245\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexponent\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mint\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[1;32m 4246\u001b[0m \u001b[0mmpfr_pow_si\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbase\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexponent\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrounding_mode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
- ]
- }
- ],
- "source": [
- "rest, combi = extend_into_basis(identity_matrix(141)[1], dbdd.B)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 125,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "139 x 139 dense matrix over Rational Field (use the '.str()' method to see the entries)"
- ]
- },
- "execution_count": 125,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dbdd.B"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on built-in function gram_schmidt:\n",
- "\n",
- "gram_schmidt(...) method of sage.matrix.matrix_integer_dense.Matrix_integer_dense instance\n",
- " Matrix.gram_schmidt(self, orthonormal=False)\n",
- " File: sage/matrix/matrix2.pyx (starting at line 9511)\n",
- " \n",
- " Performs Gram-Schmidt orthogonalization on the rows of the matrix,\n",
- " returning a new matrix and a matrix accomplishing the transformation.\n",
- " \n",
- " INPUT:\n",
- " \n",
- " - ``self`` - a matrix whose rows are to be orthogonalized.\n",
- " - ``orthonormal`` - default: ``False`` - if ``True`` the\n",
- " returned orthogonal vectors are unit vectors. This keyword\n",
- " is ignored if the matrix is over ``RDF`` or ``CDF`` and the\n",
- " results are always orthonormal.\n",
- " \n",
- " OUTPUT:\n",
- " \n",
- " A pair of matrices, ``G`` and ``M`` such that if ``A``\n",
- " represents ``self``, where the parenthetical properties occur\n",
- " when ``orthonormal = True``:\n",
- " \n",
- " - ``A = M*G``\n",
- " - The rows of ``G`` are an orthogonal (resp. orthonormal)\n",
- " set of vectors.\n",
- " - ``G`` times the conjugate-transpose of ``G`` is a diagonal\n",
- " (resp. identity) matrix.\n",
- " - The row space of ``G`` equals the row space of ``A``.\n",
- " - ``M`` is a full-rank matrix with zeros above the diagonal.\n",
- " \n",
- " For exact rings, any zero vectors produced (when the original\n",
- " vectors are linearly dependent) are not output, thus the\n",
- " orthonormal set is linearly independent, and thus a basis for the\n",
- " row space of the original matrix.\n",
- " \n",
- " Any notion of a Gram-Schmidt procedure requires that the base\n",
- " ring of the matrix has a fraction field implemented. In order\n",
- " to arrive at an orthonormal set, it must be possible to construct\n",
- " square roots of the elements of the base field. In Sage, your\n",
- " best option is the field of algebraic numbers, ``QQbar``, which\n",
- " properly contains the rationals and number fields.\n",
- " \n",
- " If you have an approximate numerical matrix, then this routine\n",
- " requires that your base field be the real and complex\n",
- " double-precision floating point numbers, ``RDF`` and ``CDF``.\n",
- " In this case, the matrix is treated as having full rank, as no\n",
- " attempt is made to recognize linear dependence with approximate\n",
- " calculations.\n",
- " \n",
- " EXAMPLES:\n",
- " \n",
- " Inexact Rings, Numerical Matrices:\n",
- " \n",
- " First, the inexact rings, ``CDF`` and ``RDF``. ::\n",
- " \n",
- " sage: A = matrix(CDF, [[ 0.6454 + 0.7491*I, -0.8662 + 0.1489*I, 0.7656 - 0.00344*I],\n",
- " ....: [-0.2913 + 0.8057*I, 0.8321 + 0.8170*I, -0.6744 + 0.9248*I],\n",
- " ....: [ 0.2554 + 0.3517*I, -0.4454 - 0.1715*I, 0.8325 - 0.6282*I]])\n",
- " sage: G, M = A.gram_schmidt()\n",
- " sage: G.round(6) # random signs\n",
- " [-0.422243 - 0.490087*I 0.566698 - 0.097416*I -0.500882 + 0.002251*I]\n",
- " [-0.057002 - 0.495035*I -0.35059 - 0.625323*I 0.255514 - 0.415284*I]\n",
- " [ 0.394105 - 0.421778*I -0.392266 - 0.039345*I -0.352905 + 0.62195*I]\n",
- " sage: M.round(6) # random\n",
- " [ -1.528503 0.0 0.0]\n",
- " [ 0.459974 - 0.40061*I -1.741233 0.0]\n",
- " [-0.934304 + 0.148868*I 0.54833 + 0.073202*I -0.550725]\n",
- " sage: (A - M*G).zero_at(10^-12)\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " sage: (G*G.conjugate_transpose()) # random\n",
- " [0.9999999999999999 0.0 0.0]\n",
- " [ 0.0 0.9999999999999997 0.0]\n",
- " [ 0.0 0.0 1.0]\n",
- " \n",
- " A rectangular matrix. Note that the ``orthonormal`` keyword\n",
- " is ignored in these cases. ::\n",
- " \n",
- " sage: A = matrix(RDF, [[-0.978325, -0.751994, 0.925305, -0.200512, 0.420458],\n",
- " ....: [-0.474877, -0.983403, 0.089836, 0.132218, 0.672965]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
- " sage: G.round(6).zero_at(10^-6)\n",
- " [-0.607223 -0.466745 0.574315 -0.124453 0.260968]\n",
- " [ 0.123203 -0.617909 -0.530578 0.289773 0.487368]\n",
- " sage: M.round(6).zero_at(10^-6)\n",
- " [1.611147 0.0]\n",
- " [0.958116 0.867778]\n",
- " sage: (A-M*G).zero_at(10^-12)\n",
- " [0.0 0.0 0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0 0.0 0.0]\n",
- " sage: (G*G.transpose()).round(6).zero_at(10^-6)\n",
- " [1.0 0.0]\n",
- " [0.0 1.0]\n",
- " \n",
- " Even though a set of vectors may be linearly dependent, no effort\n",
- " is made to decide when a zero vector is really the result of a\n",
- " relation of linear dependence. So in this regard, input matrices\n",
- " are treated as being of full rank. Try one of the base rings that\n",
- " provide exact results if you need exact results. ::\n",
- " \n",
- " sage: entries = [[1,1,2], [2,1,3], [3,1,4]]\n",
- " sage: A = matrix(QQ, entries)\n",
- " sage: A.rank()\n",
- " 2\n",
- " sage: B = matrix(RDF, entries)\n",
- " sage: G, M = B.gram_schmidt()\n",
- " sage: G.round(6) # random signs\n",
- " [-0.408248 -0.408248 -0.816497]\n",
- " [ 0.707107 -0.707107 -0.0]\n",
- " [ -0.57735 -0.57735 0.57735]\n",
- " sage: M.round(10) # random\n",
- " [-2.4494897428 0.0 0.0]\n",
- " [-3.6742346142 0.7071067812 0.0]\n",
- " [-4.8989794856 1.4142135624 0.0]\n",
- " sage: (A - M*G).zero_at(1e-14)\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " [0.0 0.0 0.0]\n",
- " sage: (G*G.transpose()) # abs tol 1e-14\n",
- " [0.9999999999999997 0.0 0.0]\n",
- " [ 0.0 0.9999999999999998 0.0]\n",
- " [ 0.0 0.0 1.0]\n",
- " \n",
- " Exact Rings, Orthonormalization:\n",
- " \n",
- " To scale a vector to unit length requires taking\n",
- " a square root, which often takes us outside the base ring.\n",
- " For the integers and the rationals, the field of algebraic numbers\n",
- " (``QQbar``) is big enough to contain what we need, but the price\n",
- " is that the computations are very slow, hence mostly of value\n",
- " for small cases or instruction. Now we need to use the\n",
- " ``orthonormal`` keyword. ::\n",
- " \n",
- " sage: A = matrix(QQbar, [[6, -8, 1],\n",
- " ....: [4, 1, 3],\n",
- " ....: [6, 3, 3],\n",
- " ....: [7, 1, -5],\n",
- " ....: [7, -3, 5]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: G\n",
- " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
- " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
- " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
- " sage: M\n",
- " [ 10.04987562112089? 0 0]\n",
- " [ 1.890570661398980? 4.735582601355131? 0]\n",
- " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
- " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
- " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
- " sage: M*G-A\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " [0 0 0]\n",
- " sage: (G*G.transpose()-identity_matrix(3)).norm() < 10^-10\n",
- " True\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " After :trac:`14047`, the matrix can also be over the algebraic reals\n",
- " ``AA``::\n",
- " \n",
- " sage: A = matrix(AA, [[6, -8, 1],\n",
- " ....: [4, 1, 3],\n",
- " ....: [6, 3, 3],\n",
- " ....: [7, 1, -5],\n",
- " ....: [7, -3, 5]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: G\n",
- " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
- " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
- " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
- " sage: M\n",
- " [ 10.04987562112089? 0 0]\n",
- " [ 1.890570661398980? 4.735582601355131? 0]\n",
- " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
- " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
- " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
- " \n",
- " Starting with complex numbers with rational real and imaginary parts.\n",
- " Note the use of the conjugate-transpose when checking the\n",
- " orthonormality. ::\n",
- " \n",
- " sage: A = matrix(QQbar, [[ -2, -I - 1, 4*I + 2, -1],\n",
- " ....: [-4*I, -2*I + 17, 0, 9*I + 1],\n",
- " ....: [ 1, -2*I - 6, -I + 11, -5*I + 1]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: (M*G-A).norm() < 10^-10\n",
- " True\n",
- " sage: id3 = G*G.conjugate().transpose()\n",
- " sage: (id3 - identity_matrix(3)).norm() < 10^-10\n",
- " True\n",
- " sage: G.row_space() == A.row_space() # long time\n",
- " True\n",
- " \n",
- " A square matrix with small rank. The zero vectors produced as a\n",
- " result of linear dependence get eliminated, so the rows of ``G``\n",
- " are a basis for the row space of ``A``. ::\n",
- " \n",
- " sage: A = matrix(QQbar, [[2, -6, 3, 8],\n",
- " ....: [1, -3, 2, 5],\n",
- " ....: [0, 0, 2, 4],\n",
- " ....: [2, -6, 3, 8]])\n",
- " sage: A.change_ring(QQ).rank()\n",
- " 2\n",
- " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
- " sage: G\n",
- " [ 0.1881441736767195? -0.5644325210301583? 0.2822162605150792? 0.7525766947068779?]\n",
- " [-0.2502818123591464? 0.750845437077439? 0.3688363550555841? 0.4873908977520218?]\n",
- " sage: M\n",
- " [10.630145812734649? 0]\n",
- " [ 6.208757731331742? 0.6718090752798139?]\n",
- " [ 3.574739299857670? 2.687236301119256?]\n",
- " [10.630145812734649? 0]\n",
- " sage: M*G-A\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " sage: (G*G.transpose()-identity_matrix(2)).norm() < 10^-10\n",
- " True\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " Exact Rings, Orthogonalization:\n",
- " \n",
- " If we forego scaling orthogonal vectors to unit vectors, we\n",
- " can apply Gram-Schmidt to a much greater variety of rings.\n",
- " Use the ``orthonormal=False`` keyword (or assume it as the default).\n",
- " Note that now the orthogonality check creates a diagonal matrix\n",
- " whose diagonal entries are the squares of the lengths of the\n",
- " vectors.\n",
- " \n",
- " First, in the rationals, without involving ``QQbar``. ::\n",
- " \n",
- " sage: A = matrix(QQ, [[-1, 3, 2, 2],\n",
- " ....: [-1, 0, -1, 0],\n",
- " ....: [-1, -2, -3, -1],\n",
- " ....: [ 1, 1, 2, 0]])\n",
- " sage: A.rank()\n",
- " 3\n",
- " sage: G, M = A.gram_schmidt()\n",
- " sage: G\n",
- " [ -1 3 2 2]\n",
- " [-19/18 1/6 -8/9 1/9]\n",
- " [ 2/35 -4/35 -2/35 9/35]\n",
- " sage: M\n",
- " [ 1 0 0]\n",
- " [ -1/18 1 0]\n",
- " [-13/18 59/35 1]\n",
- " [ 1/3 -48/35 -2]\n",
- " sage: M*G-A\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " sage: G*G.transpose()\n",
- " [ 18 0 0]\n",
- " [ 0 35/18 0]\n",
- " [ 0 0 3/35]\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " A complex subfield of the complex numbers. ::\n",
- " \n",
- " sage: C.<z> = CyclotomicField(5)\n",
- " sage: A = matrix(C, [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1],\n",
- " ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z],\n",
- " ....: [-1/2*z^3 - 2*z^2 + z + 1, -z^3 + z - 2, -2*z^3 + 1/2*z^2, 2*z^2 - z + 2]])\n",
- " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
- " sage: G\n",
- " [ -z^3 - 2*z -z^3 - 1 2*z^3 - 2*z^2 + 2*z 1]\n",
- " [ 155/139*z^3 - 161/139*z^2 + 31/139*z + 13/139 -175/139*z^3 + 180/139*z^2 - 125/139*z - 142/139 230/139*z^3 + 124/139*z^2 + 6/139*z + 19/139 -14/139*z^3 + 92/139*z^2 - 6/139*z - 95/139]\n",
- " [-10359/19841*z^3 - 36739/39682*z^2 + 24961/39682*z - 11879/39682 -28209/39682*z^3 - 3671/19841*z^2 + 51549/39682*z - 38613/39682 -42769/39682*z^3 - 615/39682*z^2 - 1252/19841*z - 14392/19841 4895/19841*z^3 + 57885/39682*z^2 - 46094/19841*z + 65747/39682]\n",
- " sage: M\n",
- " [ 1 0 0]\n",
- " [ 14/139*z^3 + 47/139*z^2 + 145/139*z + 95/139 1 0]\n",
- " [ -7/278*z^3 + 199/278*z^2 + 183/139*z + 175/278 -3785/39682*z^3 + 3346/19841*z^2 - 3990/19841*z + 2039/19841 1]\n",
- " sage: M*G - A\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " [0 0 0 0]\n",
- " sage: G*G.conjugate().transpose()\n",
- " [ 15*z^3 + 15*z^2 + 28 0 0]\n",
- " [ 0 463/139*z^3 + 463/139*z^2 + 1971/139 0]\n",
- " [ 0 0 230983/19841*z^3 + 230983/19841*z^2 + 1003433/39682]\n",
- " sage: G.row_space() == A.row_space()\n",
- " True\n",
- " \n",
- " A slightly edited legacy example. ::\n",
- " \n",
- " sage: A = matrix(ZZ, 3, [-1, 2, 5, -11, 1, 1, 1, -1, -3]); A\n",
- " [ -1 2 5]\n",
- " [-11 1 1]\n",
- " [ 1 -1 -3]\n",
- " sage: G, mu = A.gram_schmidt()\n",
- " sage: G\n",
- " [ -1 2 5]\n",
- " [ -52/5 -1/5 -2]\n",
- " [ 2/187 36/187 -14/187]\n",
- " sage: mu\n",
- " [ 1 0 0]\n",
- " [ 3/5 1 0]\n",
- " [ -3/5 -7/187 1]\n",
- " sage: G.row(0) * G.row(1)\n",
- " 0\n",
- " sage: G.row(0) * G.row(2)\n",
- " 0\n",
- " sage: G.row(1) * G.row(2)\n",
- " 0\n",
- " \n",
- " The relation between mu and A is as follows. ::\n",
- " \n",
- " sage: mu*G == A\n",
- " True\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(dbdd.B.gram_schmidt)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "(G, M) = dbdd.B.gram_schmidt"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [],
- "source": [
- "v = identity_matrix(141)[1]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on function concatenate in module __main__:\n",
- "\n",
- "concatenate(L1, L2=None)\n",
- " concatenate vecs\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(concatenate)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "ename": "TypeError",
- "evalue": "base_ring (=Ambient free module of rank 141 over the principal ideal domain Integer Ring) must be a ring",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvec\u001b[0;34m(x)\u001b[0m\n",
- "\u001b[0;31mValueError\u001b[0m: The object has more than one line: can't convert to vec.",
- "\nDuring handling of the above exception, another exception occurred:\n",
- "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-10-acef844678bf>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mconcatenate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdbdd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mB\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<string>\u001b[0m in \u001b[0;36mconcatenate\u001b[0;34m(L1, L2)\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvec\u001b[0;34m(x)\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/constructor.pyx\u001b[0m in \u001b[0;36msage.matrix.constructor.matrix (build/cythonized/sage/matrix/constructor.c:2424)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 621\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;32mclass\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0mMatrixArgs\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msee\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0mtrac\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;36m24742\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 622\u001b[0m \"\"\"\n\u001b[0;32m--> 623\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mMatrixArgs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatrix\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[1;32m 624\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 625\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/args.pyx\u001b[0m in \u001b[0;36msage.matrix.args.MatrixArgs.matrix (build/cythonized/sage/matrix/args.c:7664)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 648\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 649\u001b[0m \"\"\"\n\u001b[0;32m--> 650\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfinalize\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[1;32m 651\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 652\u001b[0m \u001b[0mcdef\u001b[0m \u001b[0mMatrix\u001b[0m \u001b[0mM\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/args.pyx\u001b[0m in \u001b[0;36msage.matrix.args.MatrixArgs.finalize (build/cythonized/sage/matrix/args.c:10260)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 930\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 931\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mspace\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 932\u001b[0;31m self.space = MatrixSpace(self.base, self.nrows, self.ncols,\n\u001b[0m\u001b[1;32m 933\u001b[0m sparse=self.sparse, **self.kwds)\n\u001b[1;32m 934\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/misc/classcall_metaclass.pyx\u001b[0m in \u001b[0;36msage.misc.classcall_metaclass.ClasscallMetaclass.__call__ (build/cythonized/sage/misc/classcall_metaclass.c:1741)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 332\u001b[0m \"\"\"\n\u001b[1;32m 333\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcls\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclasscall\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 334\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcls\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclasscall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\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 335\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 336\u001b[0m \u001b[0;31m# Fast version of type.__call__(cls, *args, **kwds)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/matrix_space.py\u001b[0m in \u001b[0;36m__classcall__\u001b[0;34m(cls, base_ring, nrows, ncols, sparse, implementation)\u001b[0m\n\u001b[1;32m 458\u001b[0m \"\"\"\n\u001b[1;32m 459\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mbase_ring\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0m_Rings\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 460\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"base_ring (=%s) must be a ring\"\u001b[0m\u001b[0;34m%\u001b[0m\u001b[0mbase_ring\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 461\u001b[0m \u001b[0mnrows\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnrows\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 462\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mncols\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;31mTypeError\u001b[0m: base_ring (=Ambient free module of rank 141 over the principal ideal domain Integer Ring) must be a ring"
- ]
- }
- ],
- "source": [
- "concatenate(v, dbdd.B)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Help on function block_matrix in module sage.matrix.special:\n",
- "\n",
- "block_matrix(*args, **kwds)\n",
- " This function is available as block_matrix(...) and matrix.block(...).\n",
- " \n",
- " \n",
- " Return a larger matrix made by concatenating submatrices\n",
- " (rows first, then columns). For example, the matrix\n",
- " \n",
- " ::\n",
- " \n",
- " [ A B ]\n",
- " [ C D ]\n",
- " \n",
- " is made up of submatrices A, B, C, and D.\n",
- " \n",
- " INPUT:\n",
- " \n",
- " The block_matrix command takes a list of submatrices to add\n",
- " as blocks, optionally preceded by a ring and the number of block rows\n",
- " and block columns, and returns a matrix.\n",
- " \n",
- " The submatrices can be specified as a list of matrices (using\n",
- " ``nrows`` and ``ncols`` to determine their layout), or a list\n",
- " of lists of matrices, where each list forms a row.\n",
- " \n",
- " - ``ring`` - the base ring\n",
- " \n",
- " - ``nrows`` - the number of block rows\n",
- " \n",
- " - ``ncols`` - the number of block cols\n",
- " \n",
- " - ``sub_matrices`` - matrices (see below for syntax)\n",
- " \n",
- " - ``subdivide`` - boolean, whether or not to add\n",
- " subdivision information to the matrix\n",
- " \n",
- " - ``sparse`` - boolean, whether to make the resulting matrix sparse\n",
- " \n",
- " \n",
- " EXAMPLES::\n",
- " \n",
- " sage: A = matrix(QQ, 2, 2, [3,9,6,10])\n",
- " sage: block_matrix([ [A, -A], [~A, 100*A] ])\n",
- " [ 3 9| -3 -9]\n",
- " [ 6 10| -6 -10]\n",
- " [-----------+-----------]\n",
- " [-5/12 3/8| 300 900]\n",
- " [ 1/4 -1/8| 600 1000]\n",
- " \n",
- " If the number of submatrices in each row is the same,\n",
- " you can specify the submatrices as a single list too::\n",
- " \n",
- " sage: block_matrix(2, 2, [ A, A, A, A ])\n",
- " [ 3 9| 3 9]\n",
- " [ 6 10| 6 10]\n",
- " [-----+-----]\n",
- " [ 3 9| 3 9]\n",
- " [ 6 10| 6 10]\n",
- " \n",
- " One can use constant entries::\n",
- " \n",
- " sage: block_matrix([ [1, A], [0, 1] ])\n",
- " [ 1 0| 3 9]\n",
- " [ 0 1| 6 10]\n",
- " [-----+-----]\n",
- " [ 0 0| 1 0]\n",
- " [ 0 0| 0 1]\n",
- " \n",
- " A zero entry may represent any square or non-square zero matrix::\n",
- " \n",
- " sage: B = matrix(QQ, 1, 1, [ 1 ] )\n",
- " sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )\n",
- " sage: block_matrix([ [B, 0], [0, C] ])\n",
- " [1|0 0]\n",
- " [-+---]\n",
- " [0|2 3]\n",
- " [0|4 5]\n",
- " \n",
- " One can specify the number of rows or columns as keywords too::\n",
- " \n",
- " sage: block_matrix([A, -A, ~A, 100*A], ncols=4)\n",
- " [ 3 9| -3 -9|-5/12 3/8| 300 900]\n",
- " [ 6 10| -6 -10| 1/4 -1/8| 600 1000]\n",
- " \n",
- " sage: block_matrix([A, -A, ~A, 100*A], nrows=1)\n",
- " [ 3 9| -3 -9|-5/12 3/8| 300 900]\n",
- " [ 6 10| -6 -10| 1/4 -1/8| 600 1000]\n",
- " \n",
- " It handles base rings nicely too::\n",
- " \n",
- " sage: R.<x> = ZZ['x']\n",
- " sage: block_matrix(2, 2, [1/2, A, 0, x-1])\n",
- " [ 1/2 0| 3 9]\n",
- " [ 0 1/2| 6 10]\n",
- " [-----------+-----------]\n",
- " [ 0 0|x - 1 0]\n",
- " [ 0 0| 0 x - 1]\n",
- " \n",
- " sage: block_matrix(2, 2, [1/2, A, 0, x-1]).parent()\n",
- " Full MatrixSpace of 4 by 4 dense matrices over Univariate Polynomial Ring in x over Rational Field\n",
- " \n",
- " Subdivisions are optional. If they are disabled, the columns need not line up::\n",
- " \n",
- " sage: B = matrix(QQ, 2, 3, range(6))\n",
- " sage: block_matrix([ [~A, B], [B, ~A] ], subdivide=False)\n",
- " [-5/12 3/8 0 1 2]\n",
- " [ 1/4 -1/8 3 4 5]\n",
- " [ 0 1 2 -5/12 3/8]\n",
- " [ 3 4 5 1/4 -1/8]\n",
- " \n",
- " Without subdivisions it also deduces dimensions for scalars if possible::\n",
- " \n",
- " sage: C = matrix(ZZ, 1, 2, range(2))\n",
- " sage: block_matrix([ [ C, 0 ], [ 3, 4 ], [ 5, 6, C ] ], subdivide=False )\n",
- " [0 1 0 0]\n",
- " [3 0 4 0]\n",
- " [0 3 0 4]\n",
- " [5 6 0 1]\n",
- " \n",
- " If all submatrices are sparse (unless there are none at all), the result\n",
- " will be a sparse matrix. Otherwise it will be dense by default. The\n",
- " ``sparse`` keyword can be used to override this::\n",
- " \n",
- " sage: A = Matrix(ZZ, 2, 2, [0, 1, 0, 0], sparse=True)\n",
- " sage: block_matrix([ [ A ], [ A ] ]).parent()\n",
- " Full MatrixSpace of 4 by 2 sparse matrices over Integer Ring\n",
- " sage: block_matrix([ [ A ], [ A ] ], sparse=False).parent()\n",
- " Full MatrixSpace of 4 by 2 dense matrices over Integer Ring\n",
- " \n",
- " Consecutive zero submatrices are consolidated. ::\n",
- " \n",
- " sage: B = matrix(2, range(4))\n",
- " sage: C = matrix(2, 8, range(16))\n",
- " sage: block_matrix(2, [[B,0,0,B],[C]], subdivide=False)\n",
- " [ 0 1 0 0 0 0 0 1]\n",
- " [ 2 3 0 0 0 0 2 3]\n",
- " [ 0 1 2 3 4 5 6 7]\n",
- " [ 8 9 10 11 12 13 14 15]\n",
- " \n",
- " Ambiguity is not tolerated. ::\n",
- " \n",
- " sage: B = matrix(2, range(4))\n",
- " sage: C = matrix(2, 8, range(16))\n",
- " sage: block_matrix(2, [[B,0,B,0],[C]], subdivide=False)\n",
- " Traceback (most recent call last):\n",
- " ...\n",
- " ValueError: insufficient information to determine submatrix widths\n",
- " \n",
- " Historically, giving only a flat list of submatrices, whose number\n",
- " was a perfect square, would create a new matrix by laying out the submatrices\n",
- " in a square grid. This behavior is now deprecated. ::\n",
- " \n",
- " sage: A = matrix(2, 3, range(6))\n",
- " sage: B = matrix(3, 3, range(9))\n",
- " sage: block_matrix([A, A, B, B])\n",
- " doctest:...: DeprecationWarning: invocation of block_matrix with just a list whose length is a perfect square is deprecated. See the documentation for details.\n",
- " [0 1 2|0 1 2]\n",
- " [3 4 5|3 4 5]\n",
- " [-----+-----]\n",
- " [0 1 2|0 1 2]\n",
- " [3 4 5|3 4 5]\n",
- " [6 7 8|6 7 8]\n",
- " \n",
- " Historically, a flat list of matrices whose number is not a perfect square,\n",
- " with no specification of the number of rows or columns, would raise an error.\n",
- " This behavior continues, but could be removed when the deprecation above is\n",
- " completed. ::\n",
- " \n",
- " sage: A = matrix(2, 3, range(6))\n",
- " sage: B = matrix(3, 3, range(9))\n",
- " sage: block_matrix([A, A, A, B, B, B])\n",
- " Traceback (most recent call last):\n",
- " ...\n",
- " ValueError: must specify nrows or ncols for non-square block matrix.\n",
- " \n",
- " TESTS::\n",
- " \n",
- " sage: A = matrix(ZZ, 2, 2, [3,5,8,13])\n",
- " sage: block_matrix(A)\n",
- " [ 3 5]\n",
- " [ 8 13]\n",
- "\n"
- ]
- }
- ],
- "source": [
- "help(block_matrix)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 79,
- "metadata": {},
- "outputs": [],
- "source": [
- "n = 1\n",
- "m = n\n",
- "q = 3301\n",
- "D_s = build_centered_binomial_law(40)\n",
- "D_e = build_centered_binomial_law(40)\n",
- "d = m + n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 80,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
- "\u001b[1;33m n= 1 \t m= 1 \t q=3301 \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 97,
- "metadata": {},
- "outputs": [],
- "source": [
- "def extend_into_basis(elt, B):\n",
- " A = block_matrix(QQ, [[matrix(elt)], [B]])\n",
- " G, M = A.gram_schmidt()\n",
- " return G, M"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 98,
- "metadata": {},
- "outputs": [],
- "source": [
- "v = identity_matrix(3)[1]\n",
- "G, M = extend_into_basis(v, dbdd.D)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 102,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "Vector space of degree 4 and dimension 1 over Rational Field\n",
- "Basis matrix:\n",
- "[ 1 0 -1 0]"
- ]
- },
- "execution_count": 102,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "A = block_matrix(QQ, [[matrix(v)], [dbdd.D]])\n",
- "A.left_kernel()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 104,
- "metadata": {},
- "outputs": [],
- "source": [
- "A.LLL?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 74,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(\n",
- "[ 0 1 0 0 0]\n",
- "[ 1/3301 0 3299/3301 2404/3301 -2094/3301]\n",
- "[ 0 1/3301 2607/3301 1173/3301 -428/3301]\n",
- "[ 0 0 1 0 0]\n",
- "[ 0 0 0 1 0]\n",
- "[ 0 0 0 0 1],\n",
- "\n",
- "[ 0 1 0 0 0]\n",
- "[------------------------------------------------------]\n",
- "[ 1/3301 0 3299/3301 2404/3301 -2094/3301]\n",
- "[ 0 1/3301 2607/3301 1173/3301 -428/3301]\n",
- "[ 0 0 1 0 0]\n",
- "[ 0 0 0 1 0]\n",
- "[ 0 0 0 0 1]\n",
- ")"
- ]
- },
- "execution_count": 74,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "M*G, block_matrix(QQ, [[matrix(v)], [dbdd.D]])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 71,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[ 3301 0 0 0| 0]\n",
- "[ 0 3301 0 0| 0]\n",
- "[-3299 -2607 1 0| 0]\n",
- "[-2404 -1173 0 1| 0]\n",
- "[-----------------------+-----]\n",
- "[ 2094 428 0 0| 1]"
- ]
- },
- "execution_count": 71,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dbdd.B"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": 44,
- "metadata": {},
- "outputs": [
- {
- "ename": "KeyboardInterrupt",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-44-2bab655759d9>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mM\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minverse\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;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/matrix_rational_dense.pyx\u001b[0m in \u001b[0;36msage.matrix.matrix_rational_dense.Matrix_rational_dense.inverse (build/cythonized/sage/matrix/matrix_rational_dense.c:8696)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 728\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 729\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0malgorithm\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"flint\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 730\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_invert_flint\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[1;32m 731\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0malgorithm\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"pari\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 732\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/matrix/matrix_rational_dense.pyx\u001b[0m in \u001b[0;36msage.matrix.matrix_rational_dense.Matrix_rational_dense._invert_flint (build/cythonized/sage/matrix/matrix_rational_dense.c:8387)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 627\u001b[0m \u001b[0mcdef\u001b[0m \u001b[0mMatrix_rational_dense\u001b[0m \u001b[0mans\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 628\u001b[0m \u001b[0mans\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mMatrix_rational_dense\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__new__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mMatrix_rational_dense\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 629\u001b[0;31m \u001b[0msig_on\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[1;32m 630\u001b[0m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfmpq_mat_inv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mans\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_matrix\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_matrix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 631\u001b[0m \u001b[0msig_off\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[0;31mKeyboardInterrupt\u001b[0m: "
- ]
- }
- ],
- "source": [
- "M.inverse()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[ 0 1 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 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",
- "[3301 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 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",
- "[ 0 0 3301 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 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",
- "[ 0 0 0 3301 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 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",
- "[ 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 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",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0 0]\n",
- "[ 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 3301 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 0 0 0]\n",
- "[ 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 3301 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 0 0]\n",
- "[ 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 3301 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 0]\n",
- "[ 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 1 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",
- "[ 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 0 1 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",
- "[ 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 0 0 1 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",
- "[ 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 0 0 0 1 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",
- "[ 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 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 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",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0 0]\n",
- "[ 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 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 1 0 0 0 0]\n",
- "[ 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 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 1 0 0 0]\n",
- "[ 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 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 1 0 0]\n",
- "[ 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 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 1 0]\n",
- "[ 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 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 1]\n"
- ]
- }
- ],
- "source": [
- "print(M)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## *Leaky LWE Estimator 2**"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 167,
- "metadata": {},
- "outputs": [],
- "source": [
- "load(\"../framework/instance_gen.sage\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 106,
- "metadata": {},
- "outputs": [],
- "source": [
- "import leaky_lwe_estimator.framework as original_framework"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 168,
- "metadata": {},
- "outputs": [],
- "source": [
- "def randv(d):\n",
- " def v(i):\n",
- " return canonical_vec(d, i)\n",
- "\n",
- " vv = v(randint(0, d - 1))\n",
- " vv -= v(randint(0, d - 1))\n",
- " vv += v(randint(0, d - 1))\n",
- " vv -= v(randint(0, d - 1))\n",
- " vv += v(randint(0, d - 1))\n",
- " return vv"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 84,
- "metadata": {},
- "outputs": [],
- "source": [
- "n = 70\n",
- "m = n\n",
- "q = 3301\n",
- "D_s = build_centered_binomial_law(40)\n",
- "D_e = build_centered_binomial_law(40)\n",
- "d = m + n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 85,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
- "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
- "_ = dbdd.estimate_attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 86,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[-7 1 -1 -1 2 -3 4 2 -4 7 4 -5 1 5 -3 -2 -6 -2 8 3 -4 6 2 2 -1 -1 -3 -4 -4 1 -2 -7 3 1 2 4 4 0 -7 0 4 -1 -3 0 0 -4 3 3 0 7 -3 -6 2 -3 -1 -1 1 -4 2 -4 -3 2 -4 -1 1 -2 9 -1 3 -1 2 -1 3 3 3 -1 5 10 0 1 -4 -8 -3 1 -9 1 2 -2 1 2 -6 -5 -4 -1 -3 8 1 5 1 0 4 -2 -9 1 -1 -2 6 2 2 1 3 -7 7 -4 2 -4 -1 1 6 5 3 -7 7 -4 1 -9 0 1 -3 -6 3 2 1 1 4 -3 3 5 2 5 1]\n"
- ]
- }
- ],
- "source": [
- "print(dbdd.u_original)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 87,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate perfect hint \u001b[0m \u001b[0m \u001b[0m\n",
- "Dimension of D: (141, 140)\n"
- ]
- }
- ],
- "source": [
- "coeff = 2\n",
- "v = vec(identity_matrix(n+m)[coeff])\n",
- "l = dbdd.u_original[0,coeff]\n",
- "dbdd.integrate_perfect_hint(v, l, estimate=False)\n",
- "print(f'Dimension of D: {dbdd.D.dimensions()}')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 88,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Go... [140]\n",
- "[141->140]\n",
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=140 \t δ=1.012476 \t β=42.87 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n",
- "Dimension of D: (140, 140)\n"
- ]
- }
- ],
- "source": [
- "_ = dbdd.estimate_attack()\n",
- "print(f'Dimension of D: {dbdd.D.dimensions()}')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 89,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[1;37m integrate perfect hint \u001b[0m \u001b[0m \u001b[0m\n",
- "Dimension of D: (140, 139)\n"
- ]
- }
- ],
- "source": [
- "coeff0, coeff1 = 0,1\n",
- "v = vec(identity_matrix(n+m)[coeff0])+vec(identity_matrix(n+m)[coeff1])\n",
- "l = dbdd.u_original[0,coeff0]+dbdd.u_original[0,coeff1]\n",
- "dbdd.integrate_perfect_hint(v, l, estimate=False)\n",
- "print(f'Dimension of D: {dbdd.D.dimensions()}')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 90,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Go... [139]\n",
- "[140->139]\n",
- "\u001b[4;37m Attack Estimation \u001b[0m\n",
- "\u001b[1;33m dim=139 \t δ=1.012676 \t β=40.13 \u001b[0m\n",
- "\u001b[0m \u001b[0m\n",
- "Dimension of D: (139, 139)\n"
- ]
- }
- ],
- "source": [
- "_ = dbdd.estimate_attack()\n",
- "print(f'Dimension of D: {dbdd.D.dimensions()}')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 91,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[4;37m Running the Attack \u001b[0m\n",
- "Running BKZ-35 \u001b[0m [0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[0m \u001b[1;37;42m Success ! \u001b[0m\n",
- "\u001b[0m \u001b[0m\n"
- ]
- }
- ],
- "source": [
- "beta, solution = dbdd.attack()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 181,
- "metadata": {},
- "outputs": [],
- "source": [
- "def one_experiment(n, nb_hints, dbdd_class, initialize_method, estimate=False, estimate_at_the_beginning=False, estimate_at_the_end=False):\n",
- " m = n\n",
- " q = 3301\n",
- " D_s = build_centered_binomial_law(40)\n",
- " D_e = build_centered_binomial_law(40)\n",
- " d = m + n\n",
- " timing = np.zeros(nb_hints+1)\n",
- " \n",
- " stime = time.time()\n",
- " A, b, dbdd = initialize_method(dbdd_class, n, q, m, D_e, D_s, diag=False, verbosity=0)\n",
- " if estimate_at_the_beginning:\n",
- " _ = dbdd.estimate_attack(silent=True)\n",
- " timing[0] = time.time()-stime\n",
- " \n",
- " for num_hint in range(nb_hints):\n",
- " v = randv(m+n)\n",
- " dbdd.integrate_perfect_hint(v, dbdd.leak(v), estimate=estimate)\n",
- " timing[num_hint+1] = time.time()-stime\n",
- " \n",
- " if estimate_at_the_end and not estimate:\n",
- " raise NotImplementedError()\n",
- " # _ = dbdd.estimate_attack(silent=True)\n",
- " \n",
- " return timing"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 193,
- "metadata": {},
- "outputs": [],
- "source": [
- "import time\n",
- "def many_experiments(nb_experiments, n, nb_max_hints, dbdd_class, initialize_method, estimate=False, estimate_at_the_beginning=False):\n",
- " timing = np.zeros(nb_max_hints+1)\n",
- "\n",
- " for _ in range(nb_experiments):\n",
- " timing += one_experiment(n, nb_max_hints, dbdd_class, initialize_method, estimate=estimate, estimate_at_the_beginning=estimate_at_the_beginning)\n",
- "\n",
- " timing /= nb_experiments\n",
- " return timing"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 150,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "29"
- ]
- }
- ],
- "source": [
- "nb_experiments = 2\n",
- "nb_hints_list = list(range(30))\n",
- "timing = []\n",
- "\n",
- "import time\n",
- "for nb_hints in nb_hints_list:\n",
- " print(f'\\r{nb_hints}', end='')\n",
- " start_time = time.time()\n",
- " for _ in range(nb_experiments):\n",
- " one_experiment(70, nb_hints, DBDD, initialize_from_LWE_instance)\n",
- " timing.append((time.time() - start_time)/nb_experiments)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 160,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "<Figure size 432x288 with 1 Axes>"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "import matplotlib.pyplot as plt\n",
- "plt.plot(nb_hints_list, timing)\n",
- "plt.xlabel('Number of hints')\n",
- "plt.ylabel('Time (in s)')\n",
- "plt.title('Speed of Improved Leaky-LWE-Estimator')\n",
- "plt.show()\n",
- "None"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 226,
- "metadata": {},
- "outputs": [],
- "source": [
- "nb_max_hints = 45\n",
- "nb_experiments = 2\n",
- "n = 30"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 227,
- "metadata": {},
- "outputs": [],
- "source": [
- "timing1 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=False, estimate_at_the_beginning=False) \n",
- "timing2 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=True, estimate_at_the_beginning=True) "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 228,
- "metadata": {},
- "outputs": [],
- "source": [
- "timing3 = many_experiments(nb_experiments, n, nb_max_hints, original_framework.DBDD, original_framework.initialize_from_LWE_instance, estimate=False, estimate_at_the_beginning=False) \n",
- "timing4 = many_experiments(nb_experiments, n, nb_max_hints, original_framework.DBDD, original_framework.initialize_from_LWE_instance, estimate=True, estimate_at_the_beginning=True) "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 229,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "<Figure size 432x288 with 1 Axes>"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "import matplotlib.pyplot as plt\n",
- "plt.plot(timing1, label='Improved (never estimate)')\n",
- "plt.plot(timing2, label='Improved (always estimate)')\n",
- "plt.plot(timing3, label='Official (never estimate)')\n",
- "plt.plot(timing4, label='Official (always estimate)')\n",
- "plt.legend()\n",
- "plt.xlabel('Number of perfect hints')\n",
- "plt.ylabel('Time (in s)')\n",
- "#plt.yscale('log')\n",
- "plt.title(f'Speed of Improved Leaky-LWE-Estimator (n={n})')\n",
- "plt.savefig('comparison-speed.png')\n",
- "plt.show()\n",
- "None"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 131,
- "metadata": {},
- "outputs": [],
- "source": [
- "one_experiment(70, 2, DBDD, initialize_from_LWE_instance)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 224,
- "metadata": {},
- "outputs": [],
- "source": [
- "nb_max_hints = 7\n",
- "nb_experiments = 10\n",
- "n = 5\n",
- "timing1 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=False, estimate_at_the_beginning=False) \n",
- "timing2 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=True, estimate_at_the_beginning=True) \n",
- "timing3 = many_experiments(nb_experiments, n, nb_max_hints, original_framework.DBDD, original_framework.initialize_from_LWE_instance, estimate=False, estimate_at_the_beginning=False) \n",
- "timing4 = many_experiments(nb_experiments, n, nb_max_hints, original_framework.DBDD, original_framework.initialize_from_LWE_instance, estimate=True, estimate_at_the_beginning=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 225,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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\n",
- "text/plain": [
- "<Figure size 432x288 with 1 Axes>"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "import matplotlib.pyplot as plt\n",
- "plt.plot(timing1, label='Improved (never estimate)')\n",
- "plt.plot(timing2, label='Improved (always estimate)')\n",
- "plt.plot(timing3, label='Official (never estimate)')\n",
- "plt.plot(timing4, label='Official (always estimate)')\n",
- "plt.legend()\n",
- "plt.xlabel('Number of perfect hints')\n",
- "plt.ylabel('Time (in s)')\n",
- "#plt.yscale('log')\n",
- "plt.title(f'Speed of Improved Leaky-LWE-Estimator (n={n})')\n",
- "plt.show()\n",
- "None"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Validation Tests"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 271,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001b[3;34m Number of threads : 1 \u001b[0m\n",
- "\u001b[3;34m Number of Samples : 5 \u001b[0m\n",
- "\u001b[4;37m Validation tests \u001b[0m\n",
- "\n",
- " \n",
- " None\n",
- "hints,\t real,\t pred_full, \t pred_light,\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "Process Process-88:\n",
- "Traceback (most recent call last):\n",
- " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 297, in _bootstrap\n",
- " self.run()\n",
- " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 99, in run\n",
- " self._target(*self._args, **self._kwargs)\n",
- " File \"/home/sage/Nextcloud/Apprentissage/Telecom ParisTech/MPRI/Stages/CryptoExperts/python-packages/leaky_lwe_estimator2/Sec5.2_validation/map_drop.py\", line 17, in ff\n",
- " r = f(i + 2**16 * trial, args)\n"
- ]
- },
- {
- "ename": "KeyboardInterrupt",
- "evalue": "",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-271-e5747eab853b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'prediction_verifications.sage'\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/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/misc/persist.pyx\u001b[0m in \u001b[0;36msage.misc.persist.load (build/cythonized/sage/misc/persist.c:2538)\u001b[0;34m()\u001b[0m\n\u001b[1;32m 142\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrepl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_loadable_filename\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\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[0;32m--> 144\u001b[0;31m \u001b[0msage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrepl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mglobals\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[1;32m 145\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/repl/load.py\u001b[0m in \u001b[0;36mload\u001b[0;34m(filename, globals, attach)\u001b[0m\n\u001b[1;32m 270\u001b[0m \u001b[0madd_attached_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfpath\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 271\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfpath\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 272\u001b[0;31m \u001b[0mexec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpreparse_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\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\"\\n\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mglobals\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 273\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mext\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'.spyx'\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mext\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'.pyx'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 274\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mattach\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n",
- "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvalidation_prediction\u001b[0;34m(N_tests, N_hints, T_hints)\u001b[0m\n",
- "\u001b[0;32m/home/sage/Nextcloud/Apprentissage/Telecom ParisTech/MPRI/Stages/CryptoExperts/python-packages/leaky_lwe_estimator2/Sec5.2_validation/map_drop.py\u001b[0m in \u001b[0;36mmap_drop\u001b[0;34m(nb, threads, f, aargs, max_drop)\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[0mret\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[1;32m 30\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mthreads\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnb\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mthreads\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[0;32m---> 31\u001b[0;31m \u001b[0mret\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mreturn_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# this is blocking\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 32\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mnb\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/queues.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, block, timeout)\u001b[0m\n\u001b[1;32m 92\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mblock\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 93\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_rlock\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 94\u001b[0;31m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv_bytes\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[1;32m 95\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrelease\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[1;32m 96\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[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/connection.py\u001b[0m in \u001b[0;36mrecv_bytes\u001b[0;34m(self, maxlength)\u001b[0m\n\u001b[1;32m 214\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmaxlength\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mmaxlength\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 215\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"negative maxlength\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 216\u001b[0;31m \u001b[0mbuf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv_bytes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmaxlength\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 217\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mbuf\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_bad_message_length\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[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/connection.py\u001b[0m in \u001b[0;36m_recv_bytes\u001b[0;34m(self, maxsize)\u001b[0m\n\u001b[1;32m 405\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 406\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_recv_bytes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmaxsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\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[0;32m--> 407\u001b[0;31m \u001b[0mbuf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_recv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\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 408\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstruct\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munpack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"!i\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbuf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetvalue\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[1;32m 409\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmaxsize\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0msize\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mmaxsize\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32m/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/connection.py\u001b[0m in \u001b[0;36m_recv\u001b[0;34m(self, size, read)\u001b[0m\n\u001b[1;32m 377\u001b[0m \u001b[0mremaining\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 378\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mremaining\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 379\u001b[0;31m \u001b[0mchunk\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mremaining\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 380\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchunk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 381\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;32msrc/cysignals/signals.pyx\u001b[0m in \u001b[0;36mcysignals.signals.python_check_interrupt\u001b[0;34m()\u001b[0m\n",
- "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- " File \"<string>\", line 42, in one_experiment\n",
- " File \"<string>\", line 41, in initialize_from_LWE_instance\n",
- " File \"<string>\", line 44, in __init__\n",
- " File \"<string>\", line 264, in estimate_attack\n",
- " File \"<string>\", line 51, in decorated\n",
- " File \"<string>\", line 64, in volumes\n",
- " File \"<string>\", line 248, in degen_logdet\n",
- " File \"sage/matrix/matrix2.pyx\", line 13219, in sage.matrix.matrix2.Matrix.norm (build/cythonized/sage/matrix/matrix2.c:89623)\n",
- " return max(S.list()).real().sqrt()\n",
- " File \"sage/matrix/matrix0.pyx\", line 160, in sage.matrix.matrix0.Matrix.list (build/cythonized/sage/matrix/matrix0.c:4260)\n",
- " return list(self._list())\n",
- " File \"sage/matrix/matrix0.pyx\", line 212, in sage.matrix.matrix0.Matrix._list (build/cythonized/sage/matrix/matrix0.c:4410)\n",
- " x.append(self.get_unsafe(i, j))\n",
- " File \"sage/matrix/matrix_double_dense.pyx\", line 249, in sage.matrix.matrix_double_dense.Matrix_double_dense.get_unsafe (build/cythonized/sage/matrix/matrix_double_dense.c:4162)\n",
- " return self._sage_dtype(cnumpy.PyArray_GETITEM(self._matrix_numpy,\n",
- " File \"sage/rings/complex_double.pyx\", line 333, in sage.rings.complex_double.ComplexDoubleField_class.__call__ (build/cythonized/sage/rings/complex_double.c:5345)\n",
- " return Parent.__call__(self, x)\n",
- " File \"sage/structure/parent.pyx\", line 900, in sage.structure.parent.Parent.__call__ (build/cythonized/sage/structure/parent.c:9218)\n",
- " return mor._call_(x)\n",
- " File \"sage/categories/map.pyx\", line 1694, in sage.categories.map.FormalCompositeMap._call_ (build/cythonized/sage/categories/map.c:11607)\n",
- " x = f._call_(x)\n",
- " File \"sage/structure/coerce_maps.pyx\", line 153, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (build/cythonized/sage/structure/coerce_maps.c:4625)\n",
- " cpdef Element _call_(self, x):\n",
- " File \"sage/structure/coerce_maps.pyx\", line 156, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (build/cythonized/sage/structure/coerce_maps.c:4448)\n",
- " return C._element_constructor(x)\n",
- " File \"/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/rings/complex_field.py\", line 429, in _element_constructor_\n",
- " return ComplexNumber(self, x)\n",
- " File \"src/cysignals/signals.pyx\", line 320, in cysignals.signals.python_check_interrupt\n",
- "KeyboardInterrupt\n"
- ]
- }
- ],
- "source": [
- "load('prediction_verifications.sage')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 272,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[ 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 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 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 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n",
- "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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 -1 0 0 0 0 0 0 0 0 0 1 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 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 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",
- "[ 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 -1 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 1 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 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 1 0 0 0 0 0]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "(37, 36.6627779805685, 35.9333472121491)"
- ]
- },
- "execution_count": 272,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "one_experiment(0, (3, \"Q-Modular\"))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "SageMath 9.0",
- "language": "sage",
- "name": "sagemath"
- },
- "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.7.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
- }
|