Fork of the official github repository of the framework Leaky-LWE-Estimator, a Sage Toolkit to attack and estimate the hardness of LWE with Side Information. https://github.com/lducas/leaky-LWE-Estimator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Framework Improvements.ipynb 336KB

  1. {
  2. "cells": [
  3. {
  4. "cell_type": "markdown",
  5. "metadata": {},
  6. "source": [
  7. "# Framework Improvements"
  8. ]
  9. },
  10. {
  11. "cell_type": "code",
  12. "execution_count": 21,
  13. "metadata": {},
  14. "outputs": [],
  15. "source": [
  16. "load(\"../framework/instance_gen.sage\")"
  17. ]
  18. },
  19. {
  20. "cell_type": "code",
  21. "execution_count": 22,
  22. "metadata": {},
  23. "outputs": [],
  24. "source": [
  25. "PACKAGES_FOLDER = '/home/sage/Nextcloud/Apprentissage/Telecom ParisTech/MPRI/Stages/CryptoExperts/python-packages'\n",
  26. "import sys\n",
  27. "if PACKAGES_FOLDER not in sys.path:\n",
  28. " sys.path += [PACKAGES_FOLDER]"
  29. ]
  30. },
  31. {
  32. "cell_type": "markdown",
  33. "metadata": {},
  34. "source": [
  35. "## Dimension reduction"
  36. ]
  37. },
  38. {
  39. "cell_type": "code",
  40. "execution_count": 130,
  41. "metadata": {},
  42. "outputs": [],
  43. "source": [
  44. "n = 70\n",
  45. "m = n\n",
  46. "q = 3301\n",
  47. "D_s = build_centered_binomial_law(40)\n",
  48. "D_e = build_centered_binomial_law(40)\n",
  49. "d = m + n"
  50. ]
  51. },
  52. {
  53. "cell_type": "code",
  54. "execution_count": 131,
  55. "metadata": {},
  56. "outputs": [
  57. {
  58. "name": "stdout",
  59. "output_type": "stream",
  60. "text": [
  61. "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
  62. "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
  63. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  64. "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
  65. "\u001b[0m \u001b[0m\n"
  66. ]
  67. }
  68. ],
  69. "source": [
  70. "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
  71. "_ = dbdd.estimate_attack()"
  72. ]
  73. },
  74. {
  75. "cell_type": "code",
  76. "execution_count": 132,
  77. "metadata": {},
  78. "outputs": [
  79. {
  80. "name": "stdout",
  81. "output_type": "stream",
  82. "text": [
  83. "[ -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"
  84. ]
  85. }
  86. ],
  87. "source": [
  88. "print(dbdd.u_original)"
  89. ]
  90. },
  91. {
  92. "cell_type": "code",
  93. "execution_count": 133,
  94. "metadata": {},
  95. "outputs": [
  96. {
  97. "name": "stdout",
  98. "output_type": "stream",
  99. "text": [
  100. "\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"
  101. ]
  102. },
  103. {
  104. "data": {
  105. "text/plain": [
  106. "True"
  107. ]
  108. },
  109. "execution_count": 133,
  110. "metadata": {},
  111. "output_type": "execute_result"
  112. }
  113. ],
  114. "source": [
  115. "v = canonical_vec(n+m, 2)\n",
  116. "dbdd.integrate_perfect_hint(v, dbdd.leak(v))"
  117. ]
  118. },
  119. {
  120. "cell_type": "code",
  121. "execution_count": 57,
  122. "metadata": {},
  123. "outputs": [
  124. {
  125. "name": "stdout",
  126. "output_type": "stream",
  127. "text": [
  128. "No error in implementation: True True\n"
  129. ]
  130. }
  131. ],
  132. "source": [
  133. "V = concatenate(v, -dbdd.leak(v))\n",
  134. "gamma, data = build_standard_substitution_matrix(V, output_data=True)\n",
  135. "print('No error in implementation:', data['normalization_matrix'] == (gamma.T * gamma).inverse(), data['det'] == (gamma.T * gamma).det())"
  136. ]
  137. },
  138. {
  139. "cell_type": "code",
  140. "execution_count": 58,
  141. "metadata": {},
  142. "outputs": [
  143. {
  144. "name": "stdout",
  145. "output_type": "stream",
  146. "text": [
  147. "\u001b[1;37m integrate perfect hint \u001b[0m \u001b[0m \u001b[0m\n"
  148. ]
  149. },
  150. {
  151. "data": {
  152. "text/plain": [
  153. "True"
  154. ]
  155. },
  156. "execution_count": 58,
  157. "metadata": {},
  158. "output_type": "execute_result"
  159. }
  160. ],
  161. "source": [
  162. "v = canonical_vec(n+m, 0) + canonical_vec(n+m,1)\n",
  163. "dbdd.integrate_perfect_hint(v, dbdd.leak(v))"
  164. ]
  165. },
  166. {
  167. "cell_type": "code",
  168. "execution_count": 59,
  169. "metadata": {},
  170. "outputs": [
  171. {
  172. "name": "stdout",
  173. "output_type": "stream",
  174. "text": [
  175. "Dimension Basis = (141, 139)\n"
  176. ]
  177. }
  178. ],
  179. "source": [
  180. "print(f'Dimension Basis = {dbdd.D.dimensions()}')"
  181. ]
  182. },
  183. {
  184. "cell_type": "code",
  185. "execution_count": 60,
  186. "metadata": {},
  187. "outputs": [
  188. {
  189. "name": "stdout",
  190. "output_type": "stream",
  191. "text": [
  192. "\u001b[4;37m Running the Attack \u001b[0m\n",
  193. "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",
  194. "\u001b[0m \u001b[0m\n"
  195. ]
  196. }
  197. ],
  198. "source": [
  199. "beta, solution = dbdd.attack()"
  200. ]
  201. },
  202. {
  203. "cell_type": "code",
  204. "execution_count": 129,
  205. "metadata": {},
  206. "outputs": [
  207. {
  208. "data": {
  209. "text/plain": [
  210. "[0 0 0 0]\n",
  211. "[0 0 0 0]"
  212. ]
  213. },
  214. "execution_count": 129,
  215. "metadata": {},
  216. "output_type": "execute_result"
  217. }
  218. ],
  219. "source": [
  220. "zero_matrix(2,4)"
  221. ]
  222. },
  223. {
  224. "cell_type": "code",
  225. "execution_count": 108,
  226. "metadata": {},
  227. "outputs": [
  228. {
  229. "name": "stdout",
  230. "output_type": "stream",
  231. "text": [
  232. "[ 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"
  233. ]
  234. }
  235. ],
  236. "source": [
  237. "print(solution)"
  238. ]
  239. },
  240. {
  241. "cell_type": "code",
  242. "execution_count": null,
  243. "metadata": {
  244. "scrolled": true
  245. },
  246. "outputs": [],
  247. "source": [
  248. "print(dbdd.Gamma)"
  249. ]
  250. },
  251. {
  252. "cell_type": "markdown",
  253. "metadata": {},
  254. "source": [
  255. "## Integration of the $q$-modular hints"
  256. ]
  257. },
  258. {
  259. "cell_type": "code",
  260. "execution_count": 229,
  261. "metadata": {},
  262. "outputs": [],
  263. "source": [
  264. "load(\"../framework/instance_gen.sage\")"
  265. ]
  266. },
  267. {
  268. "cell_type": "code",
  269. "execution_count": 230,
  270. "metadata": {},
  271. "outputs": [],
  272. "source": [
  273. "n = 70\n",
  274. "m = n\n",
  275. "q = 3301\n",
  276. "D_s = build_centered_binomial_law(40)\n",
  277. "D_e = build_centered_binomial_law(40)\n",
  278. "d = m + n"
  279. ]
  280. },
  281. {
  282. "cell_type": "code",
  283. "execution_count": 231,
  284. "metadata": {},
  285. "outputs": [
  286. {
  287. "name": "stdout",
  288. "output_type": "stream",
  289. "text": [
  290. "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
  291. "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
  292. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  293. "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
  294. "\u001b[0m \u001b[0m\n"
  295. ]
  296. }
  297. ],
  298. "source": [
  299. "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
  300. "_ = dbdd.estimate_attack()"
  301. ]
  302. },
  303. {
  304. "cell_type": "code",
  305. "execution_count": 232,
  306. "metadata": {},
  307. "outputs": [
  308. {
  309. "name": "stdout",
  310. "output_type": "stream",
  311. "text": [
  312. "[ 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"
  313. ]
  314. }
  315. ],
  316. "source": [
  317. "print(dbdd.u_original)"
  318. ]
  319. },
  320. {
  321. "cell_type": "code",
  322. "execution_count": 233,
  323. "metadata": {},
  324. "outputs": [
  325. {
  326. "data": {
  327. "text/plain": [
  328. "(567.1386512297237, 419.40251829755783, 357.43739208094473)"
  329. ]
  330. },
  331. "execution_count": 233,
  332. "metadata": {},
  333. "output_type": "execute_result"
  334. }
  335. ],
  336. "source": [
  337. "dbdd.volumes()"
  338. ]
  339. },
  340. {
  341. "cell_type": "code",
  342. "execution_count": 234,
  343. "metadata": {
  344. "scrolled": true
  345. },
  346. "outputs": [
  347. {
  348. "name": "stdout",
  349. "output_type": "stream",
  350. "text": [
  351. "\u001b[1;37m integrate q modular hint \u001b[0m \u001b[0m \u001b[0m\n",
  352. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  353. "\u001b[1;33m dim=140 \t δ=1.012476 \t β=42.87 \u001b[0m\n",
  354. "\u001b[0m \u001b[0m\n"
  355. ]
  356. }
  357. ],
  358. "source": [
  359. "v = vec(identity_matrix(n+m)[2])\n",
  360. "dbdd.integrate_q_modular_hint(v, dbdd.leak(v)-q, q, estimate=False)\n",
  361. "_ = dbdd.estimate_attack()"
  362. ]
  363. },
  364. {
  365. "cell_type": "code",
  366. "execution_count": 235,
  367. "metadata": {},
  368. "outputs": [
  369. {
  370. "name": "stdout",
  371. "output_type": "stream",
  372. "text": [
  373. "\u001b[1;37m integrate q modular hint \u001b[0m \u001b[0m \u001b[0m\n"
  374. ]
  375. },
  376. {
  377. "data": {
  378. "text/plain": [
  379. "True"
  380. ]
  381. },
  382. "execution_count": 235,
  383. "metadata": {},
  384. "output_type": "execute_result"
  385. }
  386. ],
  387. "source": [
  388. "v = vec(identity_matrix(n+m)[3])\n",
  389. "dbdd.integrate_q_modular_hint(v, dbdd.leak(v)-q, q, estimate=False)"
  390. ]
  391. },
  392. {
  393. "cell_type": "code",
  394. "execution_count": 236,
  395. "metadata": {},
  396. "outputs": [
  397. {
  398. "name": "stdout",
  399. "output_type": "stream",
  400. "text": [
  401. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  402. "\u001b[1;33m dim=139 \t δ=1.012658 \t β=40.28 \u001b[0m\n",
  403. "\u001b[0m \u001b[0m\n"
  404. ]
  405. }
  406. ],
  407. "source": [
  408. "_ = dbdd.estimate_attack()"
  409. ]
  410. },
  411. {
  412. "cell_type": "code",
  413. "execution_count": 237,
  414. "metadata": {},
  415. "outputs": [
  416. {
  417. "data": {
  418. "text/plain": [
  419. "(567.1386509034968, 413.41105375044987, 360.4331240282719)"
  420. ]
  421. },
  422. "execution_count": 237,
  423. "metadata": {},
  424. "output_type": "execute_result"
  425. }
  426. ],
  427. "source": [
  428. "dbdd.volumes()"
  429. ]
  430. },
  431. {
  432. "cell_type": "code",
  433. "execution_count": 238,
  434. "metadata": {},
  435. "outputs": [
  436. {
  437. "name": "stdout",
  438. "output_type": "stream",
  439. "text": [
  440. "\u001b[4;37m Running the Attack \u001b[0m\n",
  441. "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",
  442. "\u001b[0m \u001b[0m\n"
  443. ]
  444. }
  445. ],
  446. "source": [
  447. "beta, solution = dbdd.attack()"
  448. ]
  449. },
  450. {
  451. "cell_type": "code",
  452. "execution_count": 307,
  453. "metadata": {},
  454. "outputs": [
  455. {
  456. "data": {
  457. "text/plain": [
  458. "(-86, 29)"
  459. ]
  460. },
  461. "execution_count": 307,
  462. "metadata": {},
  463. "output_type": "execute_result"
  464. }
  465. ],
  466. "source": [
  467. "Pi = matrix([[2, -5]])\n",
  468. "D = matrix([[1,0],[9,0]])\n",
  469. "(Pi*D*Pi.T).det(), (Pi*Pi.T).det()"
  470. ]
  471. },
  472. {
  473. "cell_type": "code",
  474. "execution_count": 289,
  475. "metadata": {},
  476. "outputs": [
  477. {
  478. "data": {
  479. "text/plain": [
  480. "141 x 140 dense matrix over Rational Field (use the '.str()' method to see the entries)"
  481. ]
  482. },
  483. "execution_count": 289,
  484. "metadata": {},
  485. "output_type": "execute_result"
  486. }
  487. ],
  488. "source": [
  489. "dbdd.Gamma.T.gram_schmidt()[0].T"
  490. ]
  491. },
  492. {
  493. "cell_type": "code",
  494. "execution_count": 287,
  495. "metadata": {},
  496. "outputs": [
  497. {
  498. "name": "stdout",
  499. "output_type": "stream",
  500. "text": [
  501. "Help on built-in function gram_schmidt:\n",
  502. "\n",
  503. "gram_schmidt(...) method of sage.matrix.matrix_rational_dense.Matrix_rational_dense instance\n",
  504. " Matrix.gram_schmidt(self, orthonormal=False)\n",
  505. " File: sage/matrix/matrix2.pyx (starting at line 9511)\n",
  506. " \n",
  507. " Performs Gram-Schmidt orthogonalization on the rows of the matrix,\n",
  508. " returning a new matrix and a matrix accomplishing the transformation.\n",
  509. " \n",
  510. " INPUT:\n",
  511. " \n",
  512. " - ``self`` - a matrix whose rows are to be orthogonalized.\n",
  513. " - ``orthonormal`` - default: ``False`` - if ``True`` the\n",
  514. " returned orthogonal vectors are unit vectors. This keyword\n",
  515. " is ignored if the matrix is over ``RDF`` or ``CDF`` and the\n",
  516. " results are always orthonormal.\n",
  517. " \n",
  518. " OUTPUT:\n",
  519. " \n",
  520. " A pair of matrices, ``G`` and ``M`` such that if ``A``\n",
  521. " represents ``self``, where the parenthetical properties occur\n",
  522. " when ``orthonormal = True``:\n",
  523. " \n",
  524. " - ``A = M*G``\n",
  525. " - The rows of ``G`` are an orthogonal (resp. orthonormal)\n",
  526. " set of vectors.\n",
  527. " - ``G`` times the conjugate-transpose of ``G`` is a diagonal\n",
  528. " (resp. identity) matrix.\n",
  529. " - The row space of ``G`` equals the row space of ``A``.\n",
  530. " - ``M`` is a full-rank matrix with zeros above the diagonal.\n",
  531. " \n",
  532. " For exact rings, any zero vectors produced (when the original\n",
  533. " vectors are linearly dependent) are not output, thus the\n",
  534. " orthonormal set is linearly independent, and thus a basis for the\n",
  535. " row space of the original matrix.\n",
  536. " \n",
  537. " Any notion of a Gram-Schmidt procedure requires that the base\n",
  538. " ring of the matrix has a fraction field implemented. In order\n",
  539. " to arrive at an orthonormal set, it must be possible to construct\n",
  540. " square roots of the elements of the base field. In Sage, your\n",
  541. " best option is the field of algebraic numbers, ``QQbar``, which\n",
  542. " properly contains the rationals and number fields.\n",
  543. " \n",
  544. " If you have an approximate numerical matrix, then this routine\n",
  545. " requires that your base field be the real and complex\n",
  546. " double-precision floating point numbers, ``RDF`` and ``CDF``.\n",
  547. " In this case, the matrix is treated as having full rank, as no\n",
  548. " attempt is made to recognize linear dependence with approximate\n",
  549. " calculations.\n",
  550. " \n",
  551. " EXAMPLES:\n",
  552. " \n",
  553. " Inexact Rings, Numerical Matrices:\n",
  554. " \n",
  555. " First, the inexact rings, ``CDF`` and ``RDF``. ::\n",
  556. " \n",
  557. " sage: A = matrix(CDF, [[ 0.6454 + 0.7491*I, -0.8662 + 0.1489*I, 0.7656 - 0.00344*I],\n",
  558. " ....: [-0.2913 + 0.8057*I, 0.8321 + 0.8170*I, -0.6744 + 0.9248*I],\n",
  559. " ....: [ 0.2554 + 0.3517*I, -0.4454 - 0.1715*I, 0.8325 - 0.6282*I]])\n",
  560. " sage: G, M = A.gram_schmidt()\n",
  561. " sage: G.round(6) # random signs\n",
  562. " [-0.422243 - 0.490087*I 0.566698 - 0.097416*I -0.500882 + 0.002251*I]\n",
  563. " [-0.057002 - 0.495035*I -0.35059 - 0.625323*I 0.255514 - 0.415284*I]\n",
  564. " [ 0.394105 - 0.421778*I -0.392266 - 0.039345*I -0.352905 + 0.62195*I]\n",
  565. " sage: M.round(6) # random\n",
  566. " [ -1.528503 0.0 0.0]\n",
  567. " [ 0.459974 - 0.40061*I -1.741233 0.0]\n",
  568. " [-0.934304 + 0.148868*I 0.54833 + 0.073202*I -0.550725]\n",
  569. " sage: (A - M*G).zero_at(10^-12)\n",
  570. " [0.0 0.0 0.0]\n",
  571. " [0.0 0.0 0.0]\n",
  572. " [0.0 0.0 0.0]\n",
  573. " sage: (G*G.conjugate_transpose()) # random\n",
  574. " [0.9999999999999999 0.0 0.0]\n",
  575. " [ 0.0 0.9999999999999997 0.0]\n",
  576. " [ 0.0 0.0 1.0]\n",
  577. " \n",
  578. " A rectangular matrix. Note that the ``orthonormal`` keyword\n",
  579. " is ignored in these cases. ::\n",
  580. " \n",
  581. " sage: A = matrix(RDF, [[-0.978325, -0.751994, 0.925305, -0.200512, 0.420458],\n",
  582. " ....: [-0.474877, -0.983403, 0.089836, 0.132218, 0.672965]])\n",
  583. " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
  584. " sage: G.round(6).zero_at(10^-6)\n",
  585. " [-0.607223 -0.466745 0.574315 -0.124453 0.260968]\n",
  586. " [ 0.123203 -0.617909 -0.530578 0.289773 0.487368]\n",
  587. " sage: M.round(6).zero_at(10^-6)\n",
  588. " [1.611147 0.0]\n",
  589. " [0.958116 0.867778]\n",
  590. " sage: (A-M*G).zero_at(10^-12)\n",
  591. " [0.0 0.0 0.0 0.0 0.0]\n",
  592. " [0.0 0.0 0.0 0.0 0.0]\n",
  593. " sage: (G*G.transpose()).round(6).zero_at(10^-6)\n",
  594. " [1.0 0.0]\n",
  595. " [0.0 1.0]\n",
  596. " \n",
  597. " Even though a set of vectors may be linearly dependent, no effort\n",
  598. " is made to decide when a zero vector is really the result of a\n",
  599. " relation of linear dependence. So in this regard, input matrices\n",
  600. " are treated as being of full rank. Try one of the base rings that\n",
  601. " provide exact results if you need exact results. ::\n",
  602. " \n",
  603. " sage: entries = [[1,1,2], [2,1,3], [3,1,4]]\n",
  604. " sage: A = matrix(QQ, entries)\n",
  605. " sage: A.rank()\n",
  606. " 2\n",
  607. " sage: B = matrix(RDF, entries)\n",
  608. " sage: G, M = B.gram_schmidt()\n",
  609. " sage: G.round(6) # random signs\n",
  610. " [-0.408248 -0.408248 -0.816497]\n",
  611. " [ 0.707107 -0.707107 -0.0]\n",
  612. " [ -0.57735 -0.57735 0.57735]\n",
  613. " sage: M.round(10) # random\n",
  614. " [-2.4494897428 0.0 0.0]\n",
  615. " [-3.6742346142 0.7071067812 0.0]\n",
  616. " [-4.8989794856 1.4142135624 0.0]\n",
  617. " sage: (A - M*G).zero_at(1e-14)\n",
  618. " [0.0 0.0 0.0]\n",
  619. " [0.0 0.0 0.0]\n",
  620. " [0.0 0.0 0.0]\n",
  621. " sage: (G*G.transpose()) # abs tol 1e-14\n",
  622. " [0.9999999999999997 0.0 0.0]\n",
  623. " [ 0.0 0.9999999999999998 0.0]\n",
  624. " [ 0.0 0.0 1.0]\n",
  625. " \n",
  626. " Exact Rings, Orthonormalization:\n",
  627. " \n",
  628. " To scale a vector to unit length requires taking\n",
  629. " a square root, which often takes us outside the base ring.\n",
  630. " For the integers and the rationals, the field of algebraic numbers\n",
  631. " (``QQbar``) is big enough to contain what we need, but the price\n",
  632. " is that the computations are very slow, hence mostly of value\n",
  633. " for small cases or instruction. Now we need to use the\n",
  634. " ``orthonormal`` keyword. ::\n",
  635. " \n",
  636. " sage: A = matrix(QQbar, [[6, -8, 1],\n",
  637. " ....: [4, 1, 3],\n",
  638. " ....: [6, 3, 3],\n",
  639. " ....: [7, 1, -5],\n",
  640. " ....: [7, -3, 5]])\n",
  641. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  642. " sage: G\n",
  643. " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
  644. " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
  645. " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
  646. " sage: M\n",
  647. " [ 10.04987562112089? 0 0]\n",
  648. " [ 1.890570661398980? 4.735582601355131? 0]\n",
  649. " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
  650. " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
  651. " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
  652. " sage: M*G-A\n",
  653. " [0 0 0]\n",
  654. " [0 0 0]\n",
  655. " [0 0 0]\n",
  656. " [0 0 0]\n",
  657. " [0 0 0]\n",
  658. " sage: (G*G.transpose()-identity_matrix(3)).norm() < 10^-10\n",
  659. " True\n",
  660. " sage: G.row_space() == A.row_space()\n",
  661. " True\n",
  662. " \n",
  663. " After :trac:`14047`, the matrix can also be over the algebraic reals\n",
  664. " ``AA``::\n",
  665. " \n",
  666. " sage: A = matrix(AA, [[6, -8, 1],\n",
  667. " ....: [4, 1, 3],\n",
  668. " ....: [6, 3, 3],\n",
  669. " ....: [7, 1, -5],\n",
  670. " ....: [7, -3, 5]])\n",
  671. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  672. " sage: G\n",
  673. " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
  674. " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
  675. " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
  676. " sage: M\n",
  677. " [ 10.04987562112089? 0 0]\n",
  678. " [ 1.890570661398980? 4.735582601355131? 0]\n",
  679. " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
  680. " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
  681. " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
  682. " \n",
  683. " Starting with complex numbers with rational real and imaginary parts.\n",
  684. " Note the use of the conjugate-transpose when checking the\n",
  685. " orthonormality. ::\n",
  686. " \n",
  687. " sage: A = matrix(QQbar, [[ -2, -I - 1, 4*I + 2, -1],\n",
  688. " ....: [-4*I, -2*I + 17, 0, 9*I + 1],\n",
  689. " ....: [ 1, -2*I - 6, -I + 11, -5*I + 1]])\n",
  690. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  691. " sage: (M*G-A).norm() < 10^-10\n",
  692. " True\n",
  693. " sage: id3 = G*G.conjugate().transpose()\n",
  694. " sage: (id3 - identity_matrix(3)).norm() < 10^-10\n",
  695. " True\n",
  696. " sage: G.row_space() == A.row_space() # long time\n",
  697. " True\n",
  698. " \n",
  699. " A square matrix with small rank. The zero vectors produced as a\n",
  700. " result of linear dependence get eliminated, so the rows of ``G``\n",
  701. " are a basis for the row space of ``A``. ::\n",
  702. " \n",
  703. " sage: A = matrix(QQbar, [[2, -6, 3, 8],\n",
  704. " ....: [1, -3, 2, 5],\n",
  705. " ....: [0, 0, 2, 4],\n",
  706. " ....: [2, -6, 3, 8]])\n",
  707. " sage: A.change_ring(QQ).rank()\n",
  708. " 2\n",
  709. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  710. " sage: G\n",
  711. " [ 0.1881441736767195? -0.5644325210301583? 0.2822162605150792? 0.7525766947068779?]\n",
  712. " [-0.2502818123591464? 0.750845437077439? 0.3688363550555841? 0.4873908977520218?]\n",
  713. " sage: M\n",
  714. " [10.630145812734649? 0]\n",
  715. " [ 6.208757731331742? 0.6718090752798139?]\n",
  716. " [ 3.574739299857670? 2.687236301119256?]\n",
  717. " [10.630145812734649? 0]\n",
  718. " sage: M*G-A\n",
  719. " [0 0 0 0]\n",
  720. " [0 0 0 0]\n",
  721. " [0 0 0 0]\n",
  722. " [0 0 0 0]\n",
  723. " sage: (G*G.transpose()-identity_matrix(2)).norm() < 10^-10\n",
  724. " True\n",
  725. " sage: G.row_space() == A.row_space()\n",
  726. " True\n",
  727. " \n",
  728. " Exact Rings, Orthogonalization:\n",
  729. " \n",
  730. " If we forego scaling orthogonal vectors to unit vectors, we\n",
  731. " can apply Gram-Schmidt to a much greater variety of rings.\n",
  732. " Use the ``orthonormal=False`` keyword (or assume it as the default).\n",
  733. " Note that now the orthogonality check creates a diagonal matrix\n",
  734. " whose diagonal entries are the squares of the lengths of the\n",
  735. " vectors.\n",
  736. " \n",
  737. " First, in the rationals, without involving ``QQbar``. ::\n",
  738. " \n",
  739. " sage: A = matrix(QQ, [[-1, 3, 2, 2],\n",
  740. " ....: [-1, 0, -1, 0],\n",
  741. " ....: [-1, -2, -3, -1],\n",
  742. " ....: [ 1, 1, 2, 0]])\n",
  743. " sage: A.rank()\n",
  744. " 3\n",
  745. " sage: G, M = A.gram_schmidt()\n",
  746. " sage: G\n",
  747. " [ -1 3 2 2]\n",
  748. " [-19/18 1/6 -8/9 1/9]\n",
  749. " [ 2/35 -4/35 -2/35 9/35]\n",
  750. " sage: M\n",
  751. " [ 1 0 0]\n",
  752. " [ -1/18 1 0]\n",
  753. " [-13/18 59/35 1]\n",
  754. " [ 1/3 -48/35 -2]\n",
  755. " sage: M*G-A\n",
  756. " [0 0 0 0]\n",
  757. " [0 0 0 0]\n",
  758. " [0 0 0 0]\n",
  759. " [0 0 0 0]\n",
  760. " sage: G*G.transpose()\n",
  761. " [ 18 0 0]\n",
  762. " [ 0 35/18 0]\n",
  763. " [ 0 0 3/35]\n",
  764. " sage: G.row_space() == A.row_space()\n",
  765. " True\n",
  766. " \n",
  767. " A complex subfield of the complex numbers. ::\n",
  768. " \n",
  769. " sage: C.<z> = CyclotomicField(5)\n",
  770. " sage: A = matrix(C, [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1],\n",
  771. " ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z],\n",
  772. " ....: [-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",
  773. " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
  774. " sage: G\n",
  775. " [ -z^3 - 2*z -z^3 - 1 2*z^3 - 2*z^2 + 2*z 1]\n",
  776. " [ 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",
  777. " [-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",
  778. " sage: M\n",
  779. " [ 1 0 0]\n",
  780. " [ 14/139*z^3 + 47/139*z^2 + 145/139*z + 95/139 1 0]\n",
  781. " [ -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",
  782. " sage: M*G - A\n",
  783. " [0 0 0 0]\n",
  784. " [0 0 0 0]\n",
  785. " [0 0 0 0]\n",
  786. " sage: G*G.conjugate().transpose()\n",
  787. " [ 15*z^3 + 15*z^2 + 28 0 0]\n",
  788. " [ 0 463/139*z^3 + 463/139*z^2 + 1971/139 0]\n",
  789. " [ 0 0 230983/19841*z^3 + 230983/19841*z^2 + 1003433/39682]\n",
  790. " sage: G.row_space() == A.row_space()\n",
  791. " True\n",
  792. " \n",
  793. " A slightly edited legacy example. ::\n",
  794. " \n",
  795. " sage: A = matrix(ZZ, 3, [-1, 2, 5, -11, 1, 1, 1, -1, -3]); A\n",
  796. " [ -1 2 5]\n",
  797. " [-11 1 1]\n",
  798. " [ 1 -1 -3]\n",
  799. " sage: G, mu = A.gram_schmidt()\n",
  800. " sage: G\n",
  801. " [ -1 2 5]\n",
  802. " [ -52/5 -1/5 -2]\n",
  803. " [ 2/187 36/187 -14/187]\n",
  804. " sage: mu\n",
  805. " [ 1 0 0]\n",
  806. " [ 3/5 1 0]\n",
  807. " [ -3/5 -7/187 1]\n",
  808. " sage: G.row(0) * G.row(1)\n",
  809. " 0\n",
  810. " sage: G.row(0) * G.row(2)\n",
  811. " 0\n",
  812. " sage: G.row(1) * G.row(2)\n",
  813. " 0\n",
  814. " \n",
  815. " The relation between mu and A is as follows. ::\n",
  816. " \n",
  817. " sage: mu*G == A\n",
  818. " True\n",
  819. "\n"
  820. ]
  821. }
  822. ],
  823. "source": [
  824. "help(dbdd.Gamma.gram_schmidt)"
  825. ]
  826. },
  827. {
  828. "cell_type": "code",
  829. "execution_count": 277,
  830. "metadata": {},
  831. "outputs": [
  832. {
  833. "name": "stdout",
  834. "output_type": "stream",
  835. "text": [
  836. "<class 'sage.rings.rational.Rational'>\n",
  837. "<class 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> <class 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'>\n"
  838. ]
  839. }
  840. ],
  841. "source": [
  842. "solution = dbdd.reduced_solution \n",
  843. "\n",
  844. "for instruc_type, Gamma, data in dbdd._restoration_instructions[::-1]:\n",
  845. " solution = solution * Gamma.T\n",
  846. " if instruc_type == SUBSTITUTION:\n",
  847. " pass\n",
  848. " elif instruc_type == QMODULUS_SUBSTITUTION:\n",
  849. " print(type(solution[0].inner_product(data['v'][0])))\n",
  850. " print(type(data['v']), type(data['w']))\n",
  851. " solution += data['w'] * round(solution[0].inner_product(data['v'][0])/data['q'])\n",
  852. " else:\n",
  853. " solution += data['w'] * data['func'](solution)"
  854. ]
  855. },
  856. {
  857. "cell_type": "code",
  858. "execution_count": 265,
  859. "metadata": {},
  860. "outputs": [
  861. {
  862. "data": {
  863. "text/plain": [
  864. "140 x 140 dense matrix over Rational Field (use the '.str()' method to see the entries)"
  865. ]
  866. },
  867. "execution_count": 265,
  868. "metadata": {},
  869. "output_type": "execute_result"
  870. }
  871. ],
  872. "source": [
  873. "dbdd.B"
  874. ]
  875. },
  876. {
  877. "cell_type": "code",
  878. "execution_count": 116,
  879. "metadata": {},
  880. "outputs": [
  881. {
  882. "name": "stdout",
  883. "output_type": "stream",
  884. "text": [
  885. "\u001b[1;37m integrate q modular hint \u001b[0m "
  886. ]
  887. },
  888. {
  889. "ename": "TypeError",
  890. "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'",
  891. "output_type": "error",
  892. "traceback": [
  893. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  894. "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
  895. "\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",
  896. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
  897. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
  898. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mintegrate_q_modular_hint\u001b[0;34m(self, v, l, q, w)\u001b[0m\n",
  899. "\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",
  900. "\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",
  901. "\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'"
  902. ]
  903. }
  904. ],
  905. "source": [
  906. "v = vec(identity_matrix(n+m)[3]+identity_matrix(n+m)[4])\n",
  907. "dbdd.integrate_q_modular_hint(v, dbdd.leak(v)+q, q, w=q*v)\n",
  908. "_ = dbdd.estimate_attack()"
  909. ]
  910. },
  911. {
  912. "cell_type": "code",
  913. "execution_count": 5,
  914. "metadata": {},
  915. "outputs": [
  916. {
  917. "name": "stdout",
  918. "output_type": "stream",
  919. "text": [
  920. "\u001b[1;37m integrate q modular hint \u001b[0m "
  921. ]
  922. },
  923. {
  924. "ename": "AttributeError",
  925. "evalue": "'DBDD' object has no attribute 'gamma'",
  926. "output_type": "error",
  927. "traceback": [
  928. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  929. "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
  930. "\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",
  931. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
  932. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mdecorated\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n",
  933. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mintegrate_q_modular_hint\u001b[0;34m(self, v, l, q, w)\u001b[0m\n",
  934. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mget_reduced_vector\u001b[0;34m(self, V)\u001b[0m\n",
  935. "\u001b[0;31mAttributeError\u001b[0m: 'DBDD' object has no attribute 'gamma'"
  936. ]
  937. }
  938. ],
  939. "source": [
  940. "coeff = 2\n",
  941. "v = vec(identity_matrix(n+m)[coeff])\n",
  942. "l = dbdd.u_original[0,coeff] + 100*q\n",
  943. "dbdd.integrate_q_modular_hint(v, l, q)"
  944. ]
  945. },
  946. {
  947. "cell_type": "code",
  948. "execution_count": 244,
  949. "metadata": {},
  950. "outputs": [
  951. {
  952. "name": "stdout",
  953. "output_type": "stream",
  954. "text": [
  955. "[ -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"
  956. ]
  957. }
  958. ],
  959. "source": [
  960. "print(solution)"
  961. ]
  962. },
  963. {
  964. "cell_type": "code",
  965. "execution_count": 233,
  966. "metadata": {},
  967. "outputs": [
  968. {
  969. "data": {
  970. "text/plain": [
  971. "'[ 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]'"
  972. ]
  973. },
  974. "execution_count": 233,
  975. "metadata": {},
  976. "output_type": "execute_result"
  977. }
  978. ],
  979. "source": [
  980. "solution = solution.apply_map(lambda x: dbdd.center(x,dbdd.q))\n",
  981. "solution.str()"
  982. ]
  983. },
  984. {
  985. "cell_type": "code",
  986. "execution_count": 61,
  987. "metadata": {},
  988. "outputs": [
  989. {
  990. "name": "stdout",
  991. "output_type": "stream",
  992. "text": [
  993. "5 <class 'sage.rings.rational.Rational'> <class 'sage.matrix.matrix_rational_dense.Matrix_rational_dense'>\n",
  994. "6\n",
  995. "3\n"
  996. ]
  997. }
  998. ],
  999. "source": [
  1000. "V_ = V\n",
  1001. "_, pivot = V_.nonzero_positions()[0]\n",
  1002. "dim = dbdd.D.ncols()\n",
  1003. "\n",
  1004. "V1 = V_[0,:pivot] / V_[0,pivot]\n",
  1005. "V2 = V_[0,pivot+1:] / V_[0,pivot]\n",
  1006. "\n",
  1007. "if data is not None:\n",
  1008. " norm2 = 1 + scal(V1*V1.T) + scal(V2*V2.T)\n",
  1009. " print(5, type(norm2), type(V1.T*V1))\n",
  1010. " normalization_matrix = zero_matrix(QQ, dim-1,dim-1)\n",
  1011. " normalization_matrix[:pivot,:pivot] = identity_matrix(pivot) - V1.T*V1 / norm2\n",
  1012. " print(6)\n",
  1013. " normalization_matrix[pivot:,pivot:] = identity_matrix(dim-pivot-1) - V2.T*V2 / norm2\n",
  1014. " print(3)\n",
  1015. " normalization_matrix[:pivot,pivot:] = - V1.T*V2 / norm2\n",
  1016. " normalization_matrix[pivot:,:pivot] = - V2.T*V1 / norm2\n",
  1017. "\n",
  1018. " data['det'] = norm2\n",
  1019. " data['normalization_matrix'] = normalization_matrix"
  1020. ]
  1021. },
  1022. {
  1023. "cell_type": "code",
  1024. "execution_count": 55,
  1025. "metadata": {},
  1026. "outputs": [
  1027. {
  1028. "data": {
  1029. "text/plain": [
  1030. "[1 0]\n",
  1031. "[0 1]"
  1032. ]
  1033. },
  1034. "execution_count": 55,
  1035. "metadata": {},
  1036. "output_type": "execute_result"
  1037. }
  1038. ],
  1039. "source": [
  1040. "identity_matrix(pivot) - V1.T*V1 / norm2"
  1041. ]
  1042. },
  1043. {
  1044. "cell_type": "code",
  1045. "execution_count": 57,
  1046. "metadata": {},
  1047. "outputs": [
  1048. {
  1049. "data": {
  1050. "text/plain": [
  1051. "138 x 138 dense matrix over Rational Field (use the '.str()' method to see the entries)"
  1052. ]
  1053. },
  1054. "execution_count": 57,
  1055. "metadata": {},
  1056. "output_type": "execute_result"
  1057. }
  1058. ],
  1059. "source": [
  1060. "identity_matrix(dim-pivot-1) - V2.T*V2 / norm2"
  1061. ]
  1062. },
  1063. {
  1064. "cell_type": "code",
  1065. "execution_count": 58,
  1066. "metadata": {},
  1067. "outputs": [
  1068. {
  1069. "data": {
  1070. "text/plain": [
  1071. "140 x 140 dense matrix over Integer Ring (use the '.str()' method to see the entries)"
  1072. ]
  1073. },
  1074. "execution_count": 58,
  1075. "metadata": {},
  1076. "output_type": "execute_result"
  1077. }
  1078. ],
  1079. "source": [
  1080. "normalization_matrix"
  1081. ]
  1082. },
  1083. {
  1084. "cell_type": "code",
  1085. "execution_count": 201,
  1086. "metadata": {},
  1087. "outputs": [
  1088. {
  1089. "name": "stdout",
  1090. "output_type": "stream",
  1091. "text": [
  1092. "Help on method map_item in module sage.categories.modules_with_basis:\n",
  1093. "\n",
  1094. "map_item(f) method of sage.matrix.matrix_integer_dense.Matrix_integer_dense instance\n",
  1095. " Mapping a function on items.\n",
  1096. " \n",
  1097. " INPUT:\n",
  1098. " \n",
  1099. " - ``f`` -- a function mapping pairs ``(index, coeff)`` to\n",
  1100. " other such pairs\n",
  1101. " \n",
  1102. " Return a new element of ``self.parent()`` obtained by\n",
  1103. " applying the function `f` to all items ``(index, coeff)`` of\n",
  1104. " ``self``.\n",
  1105. " \n",
  1106. " EXAMPLES::\n",
  1107. " \n",
  1108. " sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1])\n",
  1109. " sage: x = B.an_element(); x\n",
  1110. " 2*B[-1] + 2*B[0] + 3*B[1]\n",
  1111. " sage: x.map_item(lambda i, c: (-i, 2*c))\n",
  1112. " 6*B[-1] + 4*B[0] + 4*B[1]\n",
  1113. " \n",
  1114. " ``f`` needs not be injective::\n",
  1115. " \n",
  1116. " sage: x.map_item(lambda i, c: (1, 2*c))\n",
  1117. " 14*B[1]\n",
  1118. " \n",
  1119. " sage: s = SymmetricFunctions(QQ).schur()\n",
  1120. " sage: f = lambda m,c: (m.conjugate(), 2*c)\n",
  1121. " sage: a = s([2,1]) + s([1,1,1])\n",
  1122. " sage: a.map_item(f)\n",
  1123. " 2*s[2, 1] + 2*s[3]\n",
  1124. "\n"
  1125. ]
  1126. }
  1127. ],
  1128. "source": [
  1129. "help(V.map_item)"
  1130. ]
  1131. },
  1132. {
  1133. "cell_type": "code",
  1134. "execution_count": 226,
  1135. "metadata": {},
  1136. "outputs": [
  1137. {
  1138. "data": {
  1139. "text/plain": [
  1140. "[1 1 0 0 0 0 0 0 0 0]"
  1141. ]
  1142. },
  1143. "execution_count": 226,
  1144. "metadata": {},
  1145. "output_type": "execute_result"
  1146. }
  1147. ],
  1148. "source": [
  1149. "V[0,:10]"
  1150. ]
  1151. },
  1152. {
  1153. "cell_type": "code",
  1154. "execution_count": 227,
  1155. "metadata": {},
  1156. "outputs": [
  1157. {
  1158. "data": {
  1159. "text/plain": [
  1160. "[6 6 5 5 5 5 5 5 5 5]"
  1161. ]
  1162. },
  1163. "execution_count": 227,
  1164. "metadata": {},
  1165. "output_type": "execute_result"
  1166. }
  1167. ],
  1168. "source": [
  1169. "V[0,:10].apply_map(lambda x: x+5)"
  1170. ]
  1171. },
  1172. {
  1173. "cell_type": "markdown",
  1174. "metadata": {},
  1175. "source": [
  1176. "## Forced dimension reduction"
  1177. ]
  1178. },
  1179. {
  1180. "cell_type": "code",
  1181. "execution_count": 1,
  1182. "metadata": {},
  1183. "outputs": [],
  1184. "source": [
  1185. "load(\"../framework/instance_gen.sage\")"
  1186. ]
  1187. },
  1188. {
  1189. "cell_type": "code",
  1190. "execution_count": 2,
  1191. "metadata": {},
  1192. "outputs": [],
  1193. "source": [
  1194. "n = 70\n",
  1195. "m = n\n",
  1196. "q = 3301\n",
  1197. "D_s = build_centered_binomial_law(40)\n",
  1198. "D_e = build_centered_binomial_law(40)\n",
  1199. "d = m + n"
  1200. ]
  1201. },
  1202. {
  1203. "cell_type": "code",
  1204. "execution_count": 3,
  1205. "metadata": {},
  1206. "outputs": [
  1207. {
  1208. "name": "stdout",
  1209. "output_type": "stream",
  1210. "text": [
  1211. "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
  1212. "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
  1213. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  1214. "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
  1215. "\u001b[0m \u001b[0m\n"
  1216. ]
  1217. }
  1218. ],
  1219. "source": [
  1220. "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
  1221. "_ = dbdd.estimate_attack()"
  1222. ]
  1223. },
  1224. {
  1225. "cell_type": "code",
  1226. "execution_count": 4,
  1227. "metadata": {},
  1228. "outputs": [
  1229. {
  1230. "data": {
  1231. "text/plain": [
  1232. "141 x 141 dense matrix over Integer Ring (use the '.str()' method to see the entries)"
  1233. ]
  1234. },
  1235. "execution_count": 4,
  1236. "metadata": {},
  1237. "output_type": "execute_result"
  1238. }
  1239. ],
  1240. "source": [
  1241. "dbdd.B"
  1242. ]
  1243. },
  1244. {
  1245. "cell_type": "code",
  1246. "execution_count": 16,
  1247. "metadata": {},
  1248. "outputs": [],
  1249. "source": [
  1250. "I = identity_matrix(5)"
  1251. ]
  1252. },
  1253. {
  1254. "cell_type": "code",
  1255. "execution_count": 17,
  1256. "metadata": {},
  1257. "outputs": [],
  1258. "source": [
  1259. "I[2,2]=0"
  1260. ]
  1261. },
  1262. {
  1263. "cell_type": "code",
  1264. "execution_count": 26,
  1265. "metadata": {},
  1266. "outputs": [
  1267. {
  1268. "data": {
  1269. "text/plain": [
  1270. "0"
  1271. ]
  1272. },
  1273. "execution_count": 26,
  1274. "metadata": {},
  1275. "output_type": "execute_result"
  1276. }
  1277. ],
  1278. "source": [
  1279. "min([i for i in range(I.nrows()) if not I[i].is_zero()])"
  1280. ]
  1281. },
  1282. {
  1283. "cell_type": "code",
  1284. "execution_count": 14,
  1285. "metadata": {},
  1286. "outputs": [
  1287. {
  1288. "data": {
  1289. "text/plain": [
  1290. "5"
  1291. ]
  1292. },
  1293. "execution_count": 14,
  1294. "metadata": {},
  1295. "output_type": "execute_result"
  1296. }
  1297. ],
  1298. "source": [
  1299. "I.nrows()"
  1300. ]
  1301. },
  1302. {
  1303. "cell_type": "markdown",
  1304. "metadata": {},
  1305. "source": [
  1306. "## Measure the gain of time without LLL"
  1307. ]
  1308. },
  1309. {
  1310. "cell_type": "code",
  1311. "execution_count": 91,
  1312. "metadata": {},
  1313. "outputs": [],
  1314. "source": [
  1315. "load(\"../framework/instance_gen.sage\")"
  1316. ]
  1317. },
  1318. {
  1319. "cell_type": "code",
  1320. "execution_count": 92,
  1321. "metadata": {},
  1322. "outputs": [
  1323. {
  1324. "name": "stdout",
  1325. "output_type": "stream",
  1326. "text": [
  1327. "\u001b[3;34m Number of threads : 1 \u001b[0m\n",
  1328. "\u001b[3;34m Number of Samples : 5 \u001b[0m\n",
  1329. "\u001b[4;37m Validation tests \u001b[0m\n",
  1330. "\n",
  1331. " \n",
  1332. " Perfect\n",
  1333. "hints,\t real,\t pred_full, \t pred_light,\n",
  1334. "LLL... (False)141\n",
  1335. "Done.\n",
  1336. "LLL... (True)Go... [None]\n",
  1337. "[141->140]\n",
  1338. "140\n",
  1339. "Done.\n"
  1340. ]
  1341. },
  1342. {
  1343. "name": "stderr",
  1344. "output_type": "stream",
  1345. "text": [
  1346. "Process Process-85:\n",
  1347. "Traceback (most recent call last):\n",
  1348. " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 297, in _bootstrap\n",
  1349. " self.run()\n",
  1350. " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 99, in run\n",
  1351. " self._target(*self._args, **self._kwargs)\n",
  1352. " 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",
  1353. " r = f(i + 2**16 * trial, args)\n",
  1354. " File \"<string>\", line 59, in one_experiment\n",
  1355. " File \"<string>\", line 37, in decorated\n",
  1356. " File \"<string>\", line 125, in decorated\n",
  1357. " File \"<string>\", line 96, in integrate_perfect_hint\n",
  1358. " File \"<string>\", line 102, in lattice_orthogonal_section\n",
  1359. " File \"<string>\", line 55, in project_and_eliminate_dep\n",
  1360. " File \"<string>\", line 20, in projection_matrix\n",
  1361. " 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",
  1362. " return self._invert_flint()\n",
  1363. " 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",
  1364. " raise ZeroDivisionError(\"input matrix must be nonsingular\")\n",
  1365. "ZeroDivisionError: input matrix must be nonsingular\n"
  1366. ]
  1367. },
  1368. {
  1369. "ename": "KeyboardInterrupt",
  1370. "evalue": "",
  1371. "output_type": "error",
  1372. "traceback": [
  1373. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  1374. "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
  1375. "\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",
  1376. "\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",
  1377. "\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",
  1378. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n",
  1379. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvalidation_prediction\u001b[0;34m(N_tests, N_hints, T_hints)\u001b[0m\n",
  1380. "\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",
  1381. "\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",
  1382. "\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",
  1383. "\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",
  1384. "\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",
  1385. "\u001b[0;32msrc/cysignals/signals.pyx\u001b[0m in \u001b[0;36mcysignals.signals.python_check_interrupt\u001b[0;34m()\u001b[0m\n",
  1386. "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
  1387. ]
  1388. }
  1389. ],
  1390. "source": [
  1391. "load('time_verifications.sage')"
  1392. ]
  1393. },
  1394. {
  1395. "cell_type": "code",
  1396. "execution_count": 116,
  1397. "metadata": {},
  1398. "outputs": [],
  1399. "source": [
  1400. "help(dbdd.B.gram_schmidt)"
  1401. ]
  1402. },
  1403. {
  1404. "cell_type": "code",
  1405. "execution_count": 119,
  1406. "metadata": {},
  1407. "outputs": [],
  1408. "source": [
  1409. "M, G = dbdd.B.gram_schmidt()"
  1410. ]
  1411. },
  1412. {
  1413. "cell_type": "code",
  1414. "execution_count": 4,
  1415. "metadata": {},
  1416. "outputs": [],
  1417. "source": [
  1418. "B = dbdd.B"
  1419. ]
  1420. },
  1421. {
  1422. "cell_type": "code",
  1423. "execution_count": 5,
  1424. "metadata": {},
  1425. "outputs": [],
  1426. "source": [
  1427. "def extend_into_basis(elt, B):\n",
  1428. " dim = B.nrows()\n",
  1429. " linear_combinaison = zero_matrix(RR, 1, 1+dim)\n",
  1430. " \n",
  1431. " rest = B[dim-1]\n",
  1432. " for i in range(B.nrows()):\n",
  1433. " print(i)\n",
  1434. " v = elt if i==0 else B[i-1]\n",
  1435. " alpha = -rest.inner_product(v)/v.norm()\n",
  1436. " rest += v*alpha\n",
  1437. " linear_combinaison[0,i] = alpha\n",
  1438. " \n",
  1439. " print(rest)\n",
  1440. " return rest, linear_combinaison"
  1441. ]
  1442. },
  1443. {
  1444. "cell_type": "code",
  1445. "execution_count": 6,
  1446. "metadata": {},
  1447. "outputs": [
  1448. {
  1449. "name": "stdout",
  1450. "output_type": "stream",
  1451. "text": [
  1452. "0\n",
  1453. "1\n",
  1454. "2\n",
  1455. "3\n",
  1456. "4\n",
  1457. "5\n",
  1458. "6\n",
  1459. "7\n",
  1460. "8\n",
  1461. "9\n",
  1462. "10\n",
  1463. "11\n",
  1464. "12\n",
  1465. "13\n",
  1466. "14\n",
  1467. "15\n",
  1468. "16\n",
  1469. "17\n",
  1470. "18\n",
  1471. "19\n",
  1472. "20\n",
  1473. "21\n",
  1474. "22\n",
  1475. "23\n",
  1476. "24\n",
  1477. "25\n",
  1478. "26\n",
  1479. "27\n",
  1480. "28\n",
  1481. "29\n",
  1482. "30\n",
  1483. "31\n",
  1484. "32\n",
  1485. "33\n",
  1486. "34\n",
  1487. "35\n",
  1488. "36\n",
  1489. "37\n",
  1490. "38\n",
  1491. "39\n",
  1492. "40\n",
  1493. "41\n",
  1494. "42\n",
  1495. "43\n",
  1496. "44\n",
  1497. "45\n",
  1498. "46\n",
  1499. "47\n",
  1500. "48\n",
  1501. "49\n",
  1502. "50\n",
  1503. "51\n",
  1504. "52\n",
  1505. "53\n",
  1506. "54\n",
  1507. "55\n",
  1508. "56\n",
  1509. "57\n",
  1510. "58\n",
  1511. "59\n",
  1512. "60\n",
  1513. "61\n",
  1514. "62\n",
  1515. "63\n",
  1516. "64\n",
  1517. "65\n",
  1518. "66\n",
  1519. "67\n",
  1520. "68\n",
  1521. "69\n",
  1522. "70\n",
  1523. "71\n",
  1524. "72\n",
  1525. "73\n",
  1526. "74\n",
  1527. "75\n",
  1528. "76\n",
  1529. "77\n",
  1530. "78\n",
  1531. "79\n",
  1532. "80\n",
  1533. "81\n",
  1534. "82\n",
  1535. "83\n",
  1536. "84\n",
  1537. "85\n",
  1538. "86\n",
  1539. "87\n",
  1540. "88\n",
  1541. "89\n",
  1542. "90\n",
  1543. "91\n",
  1544. "92\n",
  1545. "93\n"
  1546. ]
  1547. },
  1548. {
  1549. "ename": "KeyboardInterrupt",
  1550. "evalue": "",
  1551. "output_type": "error",
  1552. "traceback": [
  1553. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  1554. "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
  1555. "\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",
  1556. "\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",
  1557. "\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",
  1558. "\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",
  1559. "\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",
  1560. "\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",
  1561. "\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",
  1562. "\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",
  1563. "\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",
  1564. "\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",
  1565. "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
  1566. ]
  1567. }
  1568. ],
  1569. "source": [
  1570. "rest, combi = extend_into_basis(identity_matrix(141)[1], dbdd.B)"
  1571. ]
  1572. },
  1573. {
  1574. "cell_type": "code",
  1575. "execution_count": 125,
  1576. "metadata": {},
  1577. "outputs": [
  1578. {
  1579. "data": {
  1580. "text/plain": [
  1581. "139 x 139 dense matrix over Rational Field (use the '.str()' method to see the entries)"
  1582. ]
  1583. },
  1584. "execution_count": 125,
  1585. "metadata": {},
  1586. "output_type": "execute_result"
  1587. }
  1588. ],
  1589. "source": [
  1590. "dbdd.B"
  1591. ]
  1592. },
  1593. {
  1594. "cell_type": "code",
  1595. "execution_count": 7,
  1596. "metadata": {},
  1597. "outputs": [
  1598. {
  1599. "name": "stdout",
  1600. "output_type": "stream",
  1601. "text": [
  1602. "Help on built-in function gram_schmidt:\n",
  1603. "\n",
  1604. "gram_schmidt(...) method of sage.matrix.matrix_integer_dense.Matrix_integer_dense instance\n",
  1605. " Matrix.gram_schmidt(self, orthonormal=False)\n",
  1606. " File: sage/matrix/matrix2.pyx (starting at line 9511)\n",
  1607. " \n",
  1608. " Performs Gram-Schmidt orthogonalization on the rows of the matrix,\n",
  1609. " returning a new matrix and a matrix accomplishing the transformation.\n",
  1610. " \n",
  1611. " INPUT:\n",
  1612. " \n",
  1613. " - ``self`` - a matrix whose rows are to be orthogonalized.\n",
  1614. " - ``orthonormal`` - default: ``False`` - if ``True`` the\n",
  1615. " returned orthogonal vectors are unit vectors. This keyword\n",
  1616. " is ignored if the matrix is over ``RDF`` or ``CDF`` and the\n",
  1617. " results are always orthonormal.\n",
  1618. " \n",
  1619. " OUTPUT:\n",
  1620. " \n",
  1621. " A pair of matrices, ``G`` and ``M`` such that if ``A``\n",
  1622. " represents ``self``, where the parenthetical properties occur\n",
  1623. " when ``orthonormal = True``:\n",
  1624. " \n",
  1625. " - ``A = M*G``\n",
  1626. " - The rows of ``G`` are an orthogonal (resp. orthonormal)\n",
  1627. " set of vectors.\n",
  1628. " - ``G`` times the conjugate-transpose of ``G`` is a diagonal\n",
  1629. " (resp. identity) matrix.\n",
  1630. " - The row space of ``G`` equals the row space of ``A``.\n",
  1631. " - ``M`` is a full-rank matrix with zeros above the diagonal.\n",
  1632. " \n",
  1633. " For exact rings, any zero vectors produced (when the original\n",
  1634. " vectors are linearly dependent) are not output, thus the\n",
  1635. " orthonormal set is linearly independent, and thus a basis for the\n",
  1636. " row space of the original matrix.\n",
  1637. " \n",
  1638. " Any notion of a Gram-Schmidt procedure requires that the base\n",
  1639. " ring of the matrix has a fraction field implemented. In order\n",
  1640. " to arrive at an orthonormal set, it must be possible to construct\n",
  1641. " square roots of the elements of the base field. In Sage, your\n",
  1642. " best option is the field of algebraic numbers, ``QQbar``, which\n",
  1643. " properly contains the rationals and number fields.\n",
  1644. " \n",
  1645. " If you have an approximate numerical matrix, then this routine\n",
  1646. " requires that your base field be the real and complex\n",
  1647. " double-precision floating point numbers, ``RDF`` and ``CDF``.\n",
  1648. " In this case, the matrix is treated as having full rank, as no\n",
  1649. " attempt is made to recognize linear dependence with approximate\n",
  1650. " calculations.\n",
  1651. " \n",
  1652. " EXAMPLES:\n",
  1653. " \n",
  1654. " Inexact Rings, Numerical Matrices:\n",
  1655. " \n",
  1656. " First, the inexact rings, ``CDF`` and ``RDF``. ::\n",
  1657. " \n",
  1658. " sage: A = matrix(CDF, [[ 0.6454 + 0.7491*I, -0.8662 + 0.1489*I, 0.7656 - 0.00344*I],\n",
  1659. " ....: [-0.2913 + 0.8057*I, 0.8321 + 0.8170*I, -0.6744 + 0.9248*I],\n",
  1660. " ....: [ 0.2554 + 0.3517*I, -0.4454 - 0.1715*I, 0.8325 - 0.6282*I]])\n",
  1661. " sage: G, M = A.gram_schmidt()\n",
  1662. " sage: G.round(6) # random signs\n",
  1663. " [-0.422243 - 0.490087*I 0.566698 - 0.097416*I -0.500882 + 0.002251*I]\n",
  1664. " [-0.057002 - 0.495035*I -0.35059 - 0.625323*I 0.255514 - 0.415284*I]\n",
  1665. " [ 0.394105 - 0.421778*I -0.392266 - 0.039345*I -0.352905 + 0.62195*I]\n",
  1666. " sage: M.round(6) # random\n",
  1667. " [ -1.528503 0.0 0.0]\n",
  1668. " [ 0.459974 - 0.40061*I -1.741233 0.0]\n",
  1669. " [-0.934304 + 0.148868*I 0.54833 + 0.073202*I -0.550725]\n",
  1670. " sage: (A - M*G).zero_at(10^-12)\n",
  1671. " [0.0 0.0 0.0]\n",
  1672. " [0.0 0.0 0.0]\n",
  1673. " [0.0 0.0 0.0]\n",
  1674. " sage: (G*G.conjugate_transpose()) # random\n",
  1675. " [0.9999999999999999 0.0 0.0]\n",
  1676. " [ 0.0 0.9999999999999997 0.0]\n",
  1677. " [ 0.0 0.0 1.0]\n",
  1678. " \n",
  1679. " A rectangular matrix. Note that the ``orthonormal`` keyword\n",
  1680. " is ignored in these cases. ::\n",
  1681. " \n",
  1682. " sage: A = matrix(RDF, [[-0.978325, -0.751994, 0.925305, -0.200512, 0.420458],\n",
  1683. " ....: [-0.474877, -0.983403, 0.089836, 0.132218, 0.672965]])\n",
  1684. " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
  1685. " sage: G.round(6).zero_at(10^-6)\n",
  1686. " [-0.607223 -0.466745 0.574315 -0.124453 0.260968]\n",
  1687. " [ 0.123203 -0.617909 -0.530578 0.289773 0.487368]\n",
  1688. " sage: M.round(6).zero_at(10^-6)\n",
  1689. " [1.611147 0.0]\n",
  1690. " [0.958116 0.867778]\n",
  1691. " sage: (A-M*G).zero_at(10^-12)\n",
  1692. " [0.0 0.0 0.0 0.0 0.0]\n",
  1693. " [0.0 0.0 0.0 0.0 0.0]\n",
  1694. " sage: (G*G.transpose()).round(6).zero_at(10^-6)\n",
  1695. " [1.0 0.0]\n",
  1696. " [0.0 1.0]\n",
  1697. " \n",
  1698. " Even though a set of vectors may be linearly dependent, no effort\n",
  1699. " is made to decide when a zero vector is really the result of a\n",
  1700. " relation of linear dependence. So in this regard, input matrices\n",
  1701. " are treated as being of full rank. Try one of the base rings that\n",
  1702. " provide exact results if you need exact results. ::\n",
  1703. " \n",
  1704. " sage: entries = [[1,1,2], [2,1,3], [3,1,4]]\n",
  1705. " sage: A = matrix(QQ, entries)\n",
  1706. " sage: A.rank()\n",
  1707. " 2\n",
  1708. " sage: B = matrix(RDF, entries)\n",
  1709. " sage: G, M = B.gram_schmidt()\n",
  1710. " sage: G.round(6) # random signs\n",
  1711. " [-0.408248 -0.408248 -0.816497]\n",
  1712. " [ 0.707107 -0.707107 -0.0]\n",
  1713. " [ -0.57735 -0.57735 0.57735]\n",
  1714. " sage: M.round(10) # random\n",
  1715. " [-2.4494897428 0.0 0.0]\n",
  1716. " [-3.6742346142 0.7071067812 0.0]\n",
  1717. " [-4.8989794856 1.4142135624 0.0]\n",
  1718. " sage: (A - M*G).zero_at(1e-14)\n",
  1719. " [0.0 0.0 0.0]\n",
  1720. " [0.0 0.0 0.0]\n",
  1721. " [0.0 0.0 0.0]\n",
  1722. " sage: (G*G.transpose()) # abs tol 1e-14\n",
  1723. " [0.9999999999999997 0.0 0.0]\n",
  1724. " [ 0.0 0.9999999999999998 0.0]\n",
  1725. " [ 0.0 0.0 1.0]\n",
  1726. " \n",
  1727. " Exact Rings, Orthonormalization:\n",
  1728. " \n",
  1729. " To scale a vector to unit length requires taking\n",
  1730. " a square root, which often takes us outside the base ring.\n",
  1731. " For the integers and the rationals, the field of algebraic numbers\n",
  1732. " (``QQbar``) is big enough to contain what we need, but the price\n",
  1733. " is that the computations are very slow, hence mostly of value\n",
  1734. " for small cases or instruction. Now we need to use the\n",
  1735. " ``orthonormal`` keyword. ::\n",
  1736. " \n",
  1737. " sage: A = matrix(QQbar, [[6, -8, 1],\n",
  1738. " ....: [4, 1, 3],\n",
  1739. " ....: [6, 3, 3],\n",
  1740. " ....: [7, 1, -5],\n",
  1741. " ....: [7, -3, 5]])\n",
  1742. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  1743. " sage: G\n",
  1744. " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
  1745. " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
  1746. " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
  1747. " sage: M\n",
  1748. " [ 10.04987562112089? 0 0]\n",
  1749. " [ 1.890570661398980? 4.735582601355131? 0]\n",
  1750. " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
  1751. " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
  1752. " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
  1753. " sage: M*G-A\n",
  1754. " [0 0 0]\n",
  1755. " [0 0 0]\n",
  1756. " [0 0 0]\n",
  1757. " [0 0 0]\n",
  1758. " [0 0 0]\n",
  1759. " sage: (G*G.transpose()-identity_matrix(3)).norm() < 10^-10\n",
  1760. " True\n",
  1761. " sage: G.row_space() == A.row_space()\n",
  1762. " True\n",
  1763. " \n",
  1764. " After :trac:`14047`, the matrix can also be over the algebraic reals\n",
  1765. " ``AA``::\n",
  1766. " \n",
  1767. " sage: A = matrix(AA, [[6, -8, 1],\n",
  1768. " ....: [4, 1, 3],\n",
  1769. " ....: [6, 3, 3],\n",
  1770. " ....: [7, 1, -5],\n",
  1771. " ....: [7, -3, 5]])\n",
  1772. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  1773. " sage: G\n",
  1774. " [ 0.5970223141259934? -0.7960297521679913? 0.09950371902099891?]\n",
  1775. " [ 0.6063218341690895? 0.5289635311888953? 0.5937772444966257?]\n",
  1776. " [ 0.5252981913594170? 0.2941669871612735? -0.798453250866314?]\n",
  1777. " sage: M\n",
  1778. " [ 10.04987562112089? 0 0]\n",
  1779. " [ 1.890570661398980? 4.735582601355131? 0]\n",
  1780. " [ 1.492555785314984? 7.006153332071100? 1.638930357041381?]\n",
  1781. " [ 2.885607851608969? 1.804330147889395? 7.963520581008761?]\n",
  1782. " [ 7.064764050490923? 5.626248468100069? -1.197679876299471?]\n",
  1783. " \n",
  1784. " Starting with complex numbers with rational real and imaginary parts.\n",
  1785. " Note the use of the conjugate-transpose when checking the\n",
  1786. " orthonormality. ::\n",
  1787. " \n",
  1788. " sage: A = matrix(QQbar, [[ -2, -I - 1, 4*I + 2, -1],\n",
  1789. " ....: [-4*I, -2*I + 17, 0, 9*I + 1],\n",
  1790. " ....: [ 1, -2*I - 6, -I + 11, -5*I + 1]])\n",
  1791. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  1792. " sage: (M*G-A).norm() < 10^-10\n",
  1793. " True\n",
  1794. " sage: id3 = G*G.conjugate().transpose()\n",
  1795. " sage: (id3 - identity_matrix(3)).norm() < 10^-10\n",
  1796. " True\n",
  1797. " sage: G.row_space() == A.row_space() # long time\n",
  1798. " True\n",
  1799. " \n",
  1800. " A square matrix with small rank. The zero vectors produced as a\n",
  1801. " result of linear dependence get eliminated, so the rows of ``G``\n",
  1802. " are a basis for the row space of ``A``. ::\n",
  1803. " \n",
  1804. " sage: A = matrix(QQbar, [[2, -6, 3, 8],\n",
  1805. " ....: [1, -3, 2, 5],\n",
  1806. " ....: [0, 0, 2, 4],\n",
  1807. " ....: [2, -6, 3, 8]])\n",
  1808. " sage: A.change_ring(QQ).rank()\n",
  1809. " 2\n",
  1810. " sage: G, M = A.gram_schmidt(orthonormal=True)\n",
  1811. " sage: G\n",
  1812. " [ 0.1881441736767195? -0.5644325210301583? 0.2822162605150792? 0.7525766947068779?]\n",
  1813. " [-0.2502818123591464? 0.750845437077439? 0.3688363550555841? 0.4873908977520218?]\n",
  1814. " sage: M\n",
  1815. " [10.630145812734649? 0]\n",
  1816. " [ 6.208757731331742? 0.6718090752798139?]\n",
  1817. " [ 3.574739299857670? 2.687236301119256?]\n",
  1818. " [10.630145812734649? 0]\n",
  1819. " sage: M*G-A\n",
  1820. " [0 0 0 0]\n",
  1821. " [0 0 0 0]\n",
  1822. " [0 0 0 0]\n",
  1823. " [0 0 0 0]\n",
  1824. " sage: (G*G.transpose()-identity_matrix(2)).norm() < 10^-10\n",
  1825. " True\n",
  1826. " sage: G.row_space() == A.row_space()\n",
  1827. " True\n",
  1828. " \n",
  1829. " Exact Rings, Orthogonalization:\n",
  1830. " \n",
  1831. " If we forego scaling orthogonal vectors to unit vectors, we\n",
  1832. " can apply Gram-Schmidt to a much greater variety of rings.\n",
  1833. " Use the ``orthonormal=False`` keyword (or assume it as the default).\n",
  1834. " Note that now the orthogonality check creates a diagonal matrix\n",
  1835. " whose diagonal entries are the squares of the lengths of the\n",
  1836. " vectors.\n",
  1837. " \n",
  1838. " First, in the rationals, without involving ``QQbar``. ::\n",
  1839. " \n",
  1840. " sage: A = matrix(QQ, [[-1, 3, 2, 2],\n",
  1841. " ....: [-1, 0, -1, 0],\n",
  1842. " ....: [-1, -2, -3, -1],\n",
  1843. " ....: [ 1, 1, 2, 0]])\n",
  1844. " sage: A.rank()\n",
  1845. " 3\n",
  1846. " sage: G, M = A.gram_schmidt()\n",
  1847. " sage: G\n",
  1848. " [ -1 3 2 2]\n",
  1849. " [-19/18 1/6 -8/9 1/9]\n",
  1850. " [ 2/35 -4/35 -2/35 9/35]\n",
  1851. " sage: M\n",
  1852. " [ 1 0 0]\n",
  1853. " [ -1/18 1 0]\n",
  1854. " [-13/18 59/35 1]\n",
  1855. " [ 1/3 -48/35 -2]\n",
  1856. " sage: M*G-A\n",
  1857. " [0 0 0 0]\n",
  1858. " [0 0 0 0]\n",
  1859. " [0 0 0 0]\n",
  1860. " [0 0 0 0]\n",
  1861. " sage: G*G.transpose()\n",
  1862. " [ 18 0 0]\n",
  1863. " [ 0 35/18 0]\n",
  1864. " [ 0 0 3/35]\n",
  1865. " sage: G.row_space() == A.row_space()\n",
  1866. " True\n",
  1867. " \n",
  1868. " A complex subfield of the complex numbers. ::\n",
  1869. " \n",
  1870. " sage: C.<z> = CyclotomicField(5)\n",
  1871. " sage: A = matrix(C, [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1],\n",
  1872. " ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z],\n",
  1873. " ....: [-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",
  1874. " sage: G, M = A.gram_schmidt(orthonormal=False)\n",
  1875. " sage: G\n",
  1876. " [ -z^3 - 2*z -z^3 - 1 2*z^3 - 2*z^2 + 2*z 1]\n",
  1877. " [ 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",
  1878. " [-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",
  1879. " sage: M\n",
  1880. " [ 1 0 0]\n",
  1881. " [ 14/139*z^3 + 47/139*z^2 + 145/139*z + 95/139 1 0]\n",
  1882. " [ -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",
  1883. " sage: M*G - A\n",
  1884. " [0 0 0 0]\n",
  1885. " [0 0 0 0]\n",
  1886. " [0 0 0 0]\n",
  1887. " sage: G*G.conjugate().transpose()\n",
  1888. " [ 15*z^3 + 15*z^2 + 28 0 0]\n",
  1889. " [ 0 463/139*z^3 + 463/139*z^2 + 1971/139 0]\n",
  1890. " [ 0 0 230983/19841*z^3 + 230983/19841*z^2 + 1003433/39682]\n",
  1891. " sage: G.row_space() == A.row_space()\n",
  1892. " True\n",
  1893. " \n",
  1894. " A slightly edited legacy example. ::\n",
  1895. " \n",
  1896. " sage: A = matrix(ZZ, 3, [-1, 2, 5, -11, 1, 1, 1, -1, -3]); A\n",
  1897. " [ -1 2 5]\n",
  1898. " [-11 1 1]\n",
  1899. " [ 1 -1 -3]\n",
  1900. " sage: G, mu = A.gram_schmidt()\n",
  1901. " sage: G\n",
  1902. " [ -1 2 5]\n",
  1903. " [ -52/5 -1/5 -2]\n",
  1904. " [ 2/187 36/187 -14/187]\n",
  1905. " sage: mu\n",
  1906. " [ 1 0 0]\n",
  1907. " [ 3/5 1 0]\n",
  1908. " [ -3/5 -7/187 1]\n",
  1909. " sage: G.row(0) * G.row(1)\n",
  1910. " 0\n",
  1911. " sage: G.row(0) * G.row(2)\n",
  1912. " 0\n",
  1913. " sage: G.row(1) * G.row(2)\n",
  1914. " 0\n",
  1915. " \n",
  1916. " The relation between mu and A is as follows. ::\n",
  1917. " \n",
  1918. " sage: mu*G == A\n",
  1919. " True\n",
  1920. "\n"
  1921. ]
  1922. }
  1923. ],
  1924. "source": [
  1925. "help(dbdd.B.gram_schmidt)"
  1926. ]
  1927. },
  1928. {
  1929. "cell_type": "code",
  1930. "execution_count": null,
  1931. "metadata": {},
  1932. "outputs": [],
  1933. "source": [
  1934. "(G, M) = dbdd.B.gram_schmidt"
  1935. ]
  1936. },
  1937. {
  1938. "cell_type": "code",
  1939. "execution_count": 8,
  1940. "metadata": {},
  1941. "outputs": [],
  1942. "source": [
  1943. "v = identity_matrix(141)[1]"
  1944. ]
  1945. },
  1946. {
  1947. "cell_type": "code",
  1948. "execution_count": 9,
  1949. "metadata": {},
  1950. "outputs": [
  1951. {
  1952. "name": "stdout",
  1953. "output_type": "stream",
  1954. "text": [
  1955. "Help on function concatenate in module __main__:\n",
  1956. "\n",
  1957. "concatenate(L1, L2=None)\n",
  1958. " concatenate vecs\n",
  1959. "\n"
  1960. ]
  1961. }
  1962. ],
  1963. "source": [
  1964. "help(concatenate)"
  1965. ]
  1966. },
  1967. {
  1968. "cell_type": "code",
  1969. "execution_count": 10,
  1970. "metadata": {},
  1971. "outputs": [
  1972. {
  1973. "ename": "TypeError",
  1974. "evalue": "base_ring (=Ambient free module of rank 141 over the principal ideal domain Integer Ring) must be a ring",
  1975. "output_type": "error",
  1976. "traceback": [
  1977. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  1978. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  1979. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvec\u001b[0;34m(x)\u001b[0m\n",
  1980. "\u001b[0;31mValueError\u001b[0m: The object has more than one line: can't convert to vec.",
  1981. "\nDuring handling of the above exception, another exception occurred:\n",
  1982. "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
  1983. "\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",
  1984. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mconcatenate\u001b[0;34m(L1, L2)\u001b[0m\n",
  1985. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvec\u001b[0;34m(x)\u001b[0m\n",
  1986. "\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",
  1987. "\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",
  1988. "\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",
  1989. "\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",
  1990. "\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",
  1991. "\u001b[0;31mTypeError\u001b[0m: base_ring (=Ambient free module of rank 141 over the principal ideal domain Integer Ring) must be a ring"
  1992. ]
  1993. }
  1994. ],
  1995. "source": [
  1996. "concatenate(v, dbdd.B)"
  1997. ]
  1998. },
  1999. {
  2000. "cell_type": "code",
  2001. "execution_count": 12,
  2002. "metadata": {},
  2003. "outputs": [
  2004. {
  2005. "name": "stdout",
  2006. "output_type": "stream",
  2007. "text": [
  2008. "Help on function block_matrix in module sage.matrix.special:\n",
  2009. "\n",
  2010. "block_matrix(*args, **kwds)\n",
  2011. " This function is available as block_matrix(...) and matrix.block(...).\n",
  2012. " \n",
  2013. " \n",
  2014. " Return a larger matrix made by concatenating submatrices\n",
  2015. " (rows first, then columns). For example, the matrix\n",
  2016. " \n",
  2017. " ::\n",
  2018. " \n",
  2019. " [ A B ]\n",
  2020. " [ C D ]\n",
  2021. " \n",
  2022. " is made up of submatrices A, B, C, and D.\n",
  2023. " \n",
  2024. " INPUT:\n",
  2025. " \n",
  2026. " The block_matrix command takes a list of submatrices to add\n",
  2027. " as blocks, optionally preceded by a ring and the number of block rows\n",
  2028. " and block columns, and returns a matrix.\n",
  2029. " \n",
  2030. " The submatrices can be specified as a list of matrices (using\n",
  2031. " ``nrows`` and ``ncols`` to determine their layout), or a list\n",
  2032. " of lists of matrices, where each list forms a row.\n",
  2033. " \n",
  2034. " - ``ring`` - the base ring\n",
  2035. " \n",
  2036. " - ``nrows`` - the number of block rows\n",
  2037. " \n",
  2038. " - ``ncols`` - the number of block cols\n",
  2039. " \n",
  2040. " - ``sub_matrices`` - matrices (see below for syntax)\n",
  2041. " \n",
  2042. " - ``subdivide`` - boolean, whether or not to add\n",
  2043. " subdivision information to the matrix\n",
  2044. " \n",
  2045. " - ``sparse`` - boolean, whether to make the resulting matrix sparse\n",
  2046. " \n",
  2047. " \n",
  2048. " EXAMPLES::\n",
  2049. " \n",
  2050. " sage: A = matrix(QQ, 2, 2, [3,9,6,10])\n",
  2051. " sage: block_matrix([ [A, -A], [~A, 100*A] ])\n",
  2052. " [ 3 9| -3 -9]\n",
  2053. " [ 6 10| -6 -10]\n",
  2054. " [-----------+-----------]\n",
  2055. " [-5/12 3/8| 300 900]\n",
  2056. " [ 1/4 -1/8| 600 1000]\n",
  2057. " \n",
  2058. " If the number of submatrices in each row is the same,\n",
  2059. " you can specify the submatrices as a single list too::\n",
  2060. " \n",
  2061. " sage: block_matrix(2, 2, [ A, A, A, A ])\n",
  2062. " [ 3 9| 3 9]\n",
  2063. " [ 6 10| 6 10]\n",
  2064. " [-----+-----]\n",
  2065. " [ 3 9| 3 9]\n",
  2066. " [ 6 10| 6 10]\n",
  2067. " \n",
  2068. " One can use constant entries::\n",
  2069. " \n",
  2070. " sage: block_matrix([ [1, A], [0, 1] ])\n",
  2071. " [ 1 0| 3 9]\n",
  2072. " [ 0 1| 6 10]\n",
  2073. " [-----+-----]\n",
  2074. " [ 0 0| 1 0]\n",
  2075. " [ 0 0| 0 1]\n",
  2076. " \n",
  2077. " A zero entry may represent any square or non-square zero matrix::\n",
  2078. " \n",
  2079. " sage: B = matrix(QQ, 1, 1, [ 1 ] )\n",
  2080. " sage: C = matrix(QQ, 2, 2, [ 2, 3, 4, 5 ] )\n",
  2081. " sage: block_matrix([ [B, 0], [0, C] ])\n",
  2082. " [1|0 0]\n",
  2083. " [-+---]\n",
  2084. " [0|2 3]\n",
  2085. " [0|4 5]\n",
  2086. " \n",
  2087. " One can specify the number of rows or columns as keywords too::\n",
  2088. " \n",
  2089. " sage: block_matrix([A, -A, ~A, 100*A], ncols=4)\n",
  2090. " [ 3 9| -3 -9|-5/12 3/8| 300 900]\n",
  2091. " [ 6 10| -6 -10| 1/4 -1/8| 600 1000]\n",
  2092. " \n",
  2093. " sage: block_matrix([A, -A, ~A, 100*A], nrows=1)\n",
  2094. " [ 3 9| -3 -9|-5/12 3/8| 300 900]\n",
  2095. " [ 6 10| -6 -10| 1/4 -1/8| 600 1000]\n",
  2096. " \n",
  2097. " It handles base rings nicely too::\n",
  2098. " \n",
  2099. " sage: R.<x> = ZZ['x']\n",
  2100. " sage: block_matrix(2, 2, [1/2, A, 0, x-1])\n",
  2101. " [ 1/2 0| 3 9]\n",
  2102. " [ 0 1/2| 6 10]\n",
  2103. " [-----------+-----------]\n",
  2104. " [ 0 0|x - 1 0]\n",
  2105. " [ 0 0| 0 x - 1]\n",
  2106. " \n",
  2107. " sage: block_matrix(2, 2, [1/2, A, 0, x-1]).parent()\n",
  2108. " Full MatrixSpace of 4 by 4 dense matrices over Univariate Polynomial Ring in x over Rational Field\n",
  2109. " \n",
  2110. " Subdivisions are optional. If they are disabled, the columns need not line up::\n",
  2111. " \n",
  2112. " sage: B = matrix(QQ, 2, 3, range(6))\n",
  2113. " sage: block_matrix([ [~A, B], [B, ~A] ], subdivide=False)\n",
  2114. " [-5/12 3/8 0 1 2]\n",
  2115. " [ 1/4 -1/8 3 4 5]\n",
  2116. " [ 0 1 2 -5/12 3/8]\n",
  2117. " [ 3 4 5 1/4 -1/8]\n",
  2118. " \n",
  2119. " Without subdivisions it also deduces dimensions for scalars if possible::\n",
  2120. " \n",
  2121. " sage: C = matrix(ZZ, 1, 2, range(2))\n",
  2122. " sage: block_matrix([ [ C, 0 ], [ 3, 4 ], [ 5, 6, C ] ], subdivide=False )\n",
  2123. " [0 1 0 0]\n",
  2124. " [3 0 4 0]\n",
  2125. " [0 3 0 4]\n",
  2126. " [5 6 0 1]\n",
  2127. " \n",
  2128. " If all submatrices are sparse (unless there are none at all), the result\n",
  2129. " will be a sparse matrix. Otherwise it will be dense by default. The\n",
  2130. " ``sparse`` keyword can be used to override this::\n",
  2131. " \n",
  2132. " sage: A = Matrix(ZZ, 2, 2, [0, 1, 0, 0], sparse=True)\n",
  2133. " sage: block_matrix([ [ A ], [ A ] ]).parent()\n",
  2134. " Full MatrixSpace of 4 by 2 sparse matrices over Integer Ring\n",
  2135. " sage: block_matrix([ [ A ], [ A ] ], sparse=False).parent()\n",
  2136. " Full MatrixSpace of 4 by 2 dense matrices over Integer Ring\n",
  2137. " \n",
  2138. " Consecutive zero submatrices are consolidated. ::\n",
  2139. " \n",
  2140. " sage: B = matrix(2, range(4))\n",
  2141. " sage: C = matrix(2, 8, range(16))\n",
  2142. " sage: block_matrix(2, [[B,0,0,B],[C]], subdivide=False)\n",
  2143. " [ 0 1 0 0 0 0 0 1]\n",
  2144. " [ 2 3 0 0 0 0 2 3]\n",
  2145. " [ 0 1 2 3 4 5 6 7]\n",
  2146. " [ 8 9 10 11 12 13 14 15]\n",
  2147. " \n",
  2148. " Ambiguity is not tolerated. ::\n",
  2149. " \n",
  2150. " sage: B = matrix(2, range(4))\n",
  2151. " sage: C = matrix(2, 8, range(16))\n",
  2152. " sage: block_matrix(2, [[B,0,B,0],[C]], subdivide=False)\n",
  2153. " Traceback (most recent call last):\n",
  2154. " ...\n",
  2155. " ValueError: insufficient information to determine submatrix widths\n",
  2156. " \n",
  2157. " Historically, giving only a flat list of submatrices, whose number\n",
  2158. " was a perfect square, would create a new matrix by laying out the submatrices\n",
  2159. " in a square grid. This behavior is now deprecated. ::\n",
  2160. " \n",
  2161. " sage: A = matrix(2, 3, range(6))\n",
  2162. " sage: B = matrix(3, 3, range(9))\n",
  2163. " sage: block_matrix([A, A, B, B])\n",
  2164. " doctest:...: DeprecationWarning: invocation of block_matrix with just a list whose length is a perfect square is deprecated. See the documentation for details.\n",
  2165. " [0 1 2|0 1 2]\n",
  2166. " [3 4 5|3 4 5]\n",
  2167. " [-----+-----]\n",
  2168. " [0 1 2|0 1 2]\n",
  2169. " [3 4 5|3 4 5]\n",
  2170. " [6 7 8|6 7 8]\n",
  2171. " \n",
  2172. " Historically, a flat list of matrices whose number is not a perfect square,\n",
  2173. " with no specification of the number of rows or columns, would raise an error.\n",
  2174. " This behavior continues, but could be removed when the deprecation above is\n",
  2175. " completed. ::\n",
  2176. " \n",
  2177. " sage: A = matrix(2, 3, range(6))\n",
  2178. " sage: B = matrix(3, 3, range(9))\n",
  2179. " sage: block_matrix([A, A, A, B, B, B])\n",
  2180. " Traceback (most recent call last):\n",
  2181. " ...\n",
  2182. " ValueError: must specify nrows or ncols for non-square block matrix.\n",
  2183. " \n",
  2184. " TESTS::\n",
  2185. " \n",
  2186. " sage: A = matrix(ZZ, 2, 2, [3,5,8,13])\n",
  2187. " sage: block_matrix(A)\n",
  2188. " [ 3 5]\n",
  2189. " [ 8 13]\n",
  2190. "\n"
  2191. ]
  2192. }
  2193. ],
  2194. "source": [
  2195. "help(block_matrix)"
  2196. ]
  2197. },
  2198. {
  2199. "cell_type": "code",
  2200. "execution_count": 79,
  2201. "metadata": {},
  2202. "outputs": [],
  2203. "source": [
  2204. "n = 1\n",
  2205. "m = n\n",
  2206. "q = 3301\n",
  2207. "D_s = build_centered_binomial_law(40)\n",
  2208. "D_e = build_centered_binomial_law(40)\n",
  2209. "d = m + n"
  2210. ]
  2211. },
  2212. {
  2213. "cell_type": "code",
  2214. "execution_count": 80,
  2215. "metadata": {},
  2216. "outputs": [
  2217. {
  2218. "name": "stdout",
  2219. "output_type": "stream",
  2220. "text": [
  2221. "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
  2222. "\u001b[1;33m n= 1 \t m= 1 \t q=3301 \u001b[0m\n"
  2223. ]
  2224. }
  2225. ],
  2226. "source": [
  2227. "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)"
  2228. ]
  2229. },
  2230. {
  2231. "cell_type": "code",
  2232. "execution_count": 97,
  2233. "metadata": {},
  2234. "outputs": [],
  2235. "source": [
  2236. "def extend_into_basis(elt, B):\n",
  2237. " A = block_matrix(QQ, [[matrix(elt)], [B]])\n",
  2238. " G, M = A.gram_schmidt()\n",
  2239. " return G, M"
  2240. ]
  2241. },
  2242. {
  2243. "cell_type": "code",
  2244. "execution_count": 98,
  2245. "metadata": {},
  2246. "outputs": [],
  2247. "source": [
  2248. "v = identity_matrix(3)[1]\n",
  2249. "G, M = extend_into_basis(v, dbdd.D)"
  2250. ]
  2251. },
  2252. {
  2253. "cell_type": "code",
  2254. "execution_count": 102,
  2255. "metadata": {},
  2256. "outputs": [
  2257. {
  2258. "data": {
  2259. "text/plain": [
  2260. "Vector space of degree 4 and dimension 1 over Rational Field\n",
  2261. "Basis matrix:\n",
  2262. "[ 1 0 -1 0]"
  2263. ]
  2264. },
  2265. "execution_count": 102,
  2266. "metadata": {},
  2267. "output_type": "execute_result"
  2268. }
  2269. ],
  2270. "source": [
  2271. "A = block_matrix(QQ, [[matrix(v)], [dbdd.D]])\n",
  2272. "A.left_kernel()"
  2273. ]
  2274. },
  2275. {
  2276. "cell_type": "code",
  2277. "execution_count": 104,
  2278. "metadata": {},
  2279. "outputs": [],
  2280. "source": [
  2281. "A.LLL?"
  2282. ]
  2283. },
  2284. {
  2285. "cell_type": "code",
  2286. "execution_count": 74,
  2287. "metadata": {},
  2288. "outputs": [
  2289. {
  2290. "data": {
  2291. "text/plain": [
  2292. "(\n",
  2293. "[ 0 1 0 0 0]\n",
  2294. "[ 1/3301 0 3299/3301 2404/3301 -2094/3301]\n",
  2295. "[ 0 1/3301 2607/3301 1173/3301 -428/3301]\n",
  2296. "[ 0 0 1 0 0]\n",
  2297. "[ 0 0 0 1 0]\n",
  2298. "[ 0 0 0 0 1],\n",
  2299. "\n",
  2300. "[ 0 1 0 0 0]\n",
  2301. "[------------------------------------------------------]\n",
  2302. "[ 1/3301 0 3299/3301 2404/3301 -2094/3301]\n",
  2303. "[ 0 1/3301 2607/3301 1173/3301 -428/3301]\n",
  2304. "[ 0 0 1 0 0]\n",
  2305. "[ 0 0 0 1 0]\n",
  2306. "[ 0 0 0 0 1]\n",
  2307. ")"
  2308. ]
  2309. },
  2310. "execution_count": 74,
  2311. "metadata": {},
  2312. "output_type": "execute_result"
  2313. }
  2314. ],
  2315. "source": [
  2316. "M*G, block_matrix(QQ, [[matrix(v)], [dbdd.D]])"
  2317. ]
  2318. },
  2319. {
  2320. "cell_type": "code",
  2321. "execution_count": 71,
  2322. "metadata": {},
  2323. "outputs": [
  2324. {
  2325. "data": {
  2326. "text/plain": [
  2327. "[ 3301 0 0 0| 0]\n",
  2328. "[ 0 3301 0 0| 0]\n",
  2329. "[-3299 -2607 1 0| 0]\n",
  2330. "[-2404 -1173 0 1| 0]\n",
  2331. "[-----------------------+-----]\n",
  2332. "[ 2094 428 0 0| 1]"
  2333. ]
  2334. },
  2335. "execution_count": 71,
  2336. "metadata": {},
  2337. "output_type": "execute_result"
  2338. }
  2339. ],
  2340. "source": [
  2341. "dbdd.B"
  2342. ]
  2343. },
  2344. {
  2345. "cell_type": "code",
  2346. "execution_count": null,
  2347. "metadata": {},
  2348. "outputs": [],
  2349. "source": []
  2350. },
  2351. {
  2352. "cell_type": "code",
  2353. "execution_count": 44,
  2354. "metadata": {},
  2355. "outputs": [
  2356. {
  2357. "ename": "KeyboardInterrupt",
  2358. "evalue": "",
  2359. "output_type": "error",
  2360. "traceback": [
  2361. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  2362. "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
  2363. "\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",
  2364. "\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",
  2365. "\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",
  2366. "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
  2367. ]
  2368. }
  2369. ],
  2370. "source": [
  2371. "M.inverse()"
  2372. ]
  2373. },
  2374. {
  2375. "cell_type": "code",
  2376. "execution_count": 27,
  2377. "metadata": {},
  2378. "outputs": [
  2379. {
  2380. "name": "stdout",
  2381. "output_type": "stream",
  2382. "text": [
  2383. "[ 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",
  2384. "[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",
  2385. "[ 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",
  2386. "[ 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",
  2387. "[ 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",
  2388. "[ 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",
  2389. "[ 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",
  2390. "[ 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",
  2391. "[ 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",
  2392. "[ 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",
  2393. "[ 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",
  2394. "[ 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",
  2395. "[ 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",
  2396. "[ 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",
  2397. "[ 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",
  2398. "[ 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",
  2399. "[ 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",
  2400. "[ 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",
  2401. "[ 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",
  2402. "[ 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",
  2403. "[ 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",
  2404. "[ 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",
  2405. "[ 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",
  2406. "[ 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",
  2407. "[ 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",
  2408. "[ 0 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",
  2409. "[ 0 0 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",
  2410. "[ 0 0 0 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",
  2411. "[ 0 0 0 0 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",
  2412. "[ 0 0 0 0 0 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",
  2413. "[ 0 0 0 0 0 0 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",
  2414. "[ 0 0 0 0 0 0 0 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",
  2415. "[ 0 0 0 0 0 0 0 0 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",
  2416. "[ 0 0 0 0 0 0 0 0 0 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",
  2417. "[ 0 0 0 0 0 0 0 0 0 0 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",
  2418. "[ 0 0 0 0 0 0 0 0 0 0 0 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",
  2419. "[ 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2420. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2421. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2422. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2423. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2424. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2425. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2426. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2427. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2428. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2429. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2430. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2431. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2432. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2433. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2434. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2435. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2436. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2437. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2438. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2439. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2440. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2441. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2442. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2443. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2444. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2445. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2446. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2447. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2448. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2449. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2450. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2451. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2452. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2453. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2454. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2455. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2456. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2457. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2458. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2459. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2460. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2461. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2462. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2463. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2464. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2465. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2466. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2467. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2468. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2469. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2470. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2471. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2472. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2473. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2474. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2475. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2476. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2477. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2478. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2479. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2480. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2481. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2482. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2483. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2484. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2485. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2486. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2487. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2488. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2489. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2490. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2491. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2492. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2493. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2494. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2495. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2496. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2497. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2498. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2499. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2500. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2501. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2502. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2503. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2504. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2505. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2506. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2507. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2508. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2509. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2510. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2511. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2512. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2513. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2514. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2515. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2516. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2517. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2518. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2519. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2520. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2521. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2522. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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",
  2523. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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"
  2524. ]
  2525. }
  2526. ],
  2527. "source": [
  2528. "print(M)"
  2529. ]
  2530. },
  2531. {
  2532. "cell_type": "markdown",
  2533. "metadata": {},
  2534. "source": [
  2535. "## *Leaky LWE Estimator 2**"
  2536. ]
  2537. },
  2538. {
  2539. "cell_type": "code",
  2540. "execution_count": 167,
  2541. "metadata": {},
  2542. "outputs": [],
  2543. "source": [
  2544. "load(\"../framework/instance_gen.sage\")"
  2545. ]
  2546. },
  2547. {
  2548. "cell_type": "code",
  2549. "execution_count": 106,
  2550. "metadata": {},
  2551. "outputs": [],
  2552. "source": [
  2553. "import leaky_lwe_estimator.framework as original_framework"
  2554. ]
  2555. },
  2556. {
  2557. "cell_type": "code",
  2558. "execution_count": 168,
  2559. "metadata": {},
  2560. "outputs": [],
  2561. "source": [
  2562. "def randv(d):\n",
  2563. " def v(i):\n",
  2564. " return canonical_vec(d, i)\n",
  2565. "\n",
  2566. " vv = v(randint(0, d - 1))\n",
  2567. " vv -= v(randint(0, d - 1))\n",
  2568. " vv += v(randint(0, d - 1))\n",
  2569. " vv -= v(randint(0, d - 1))\n",
  2570. " vv += v(randint(0, d - 1))\n",
  2571. " return vv"
  2572. ]
  2573. },
  2574. {
  2575. "cell_type": "code",
  2576. "execution_count": 84,
  2577. "metadata": {},
  2578. "outputs": [],
  2579. "source": [
  2580. "n = 70\n",
  2581. "m = n\n",
  2582. "q = 3301\n",
  2583. "D_s = build_centered_binomial_law(40)\n",
  2584. "D_e = build_centered_binomial_law(40)\n",
  2585. "d = m + n"
  2586. ]
  2587. },
  2588. {
  2589. "cell_type": "code",
  2590. "execution_count": 85,
  2591. "metadata": {},
  2592. "outputs": [
  2593. {
  2594. "name": "stdout",
  2595. "output_type": "stream",
  2596. "text": [
  2597. "\u001b[4;37m Build DBDD from LWE \u001b[0m\n",
  2598. "\u001b[1;33m n= 70 \t m= 70 \t q=3301 \u001b[0m\n",
  2599. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  2600. "\u001b[1;33m dim=141 \t δ=1.012362 \t β=45.40 \u001b[0m\n",
  2601. "\u001b[0m \u001b[0m\n"
  2602. ]
  2603. }
  2604. ],
  2605. "source": [
  2606. "A, b, dbdd = initialize_from_LWE_instance(DBDD, n, q, m, D_e, D_s, diag=False, verbosity=1)\n",
  2607. "_ = dbdd.estimate_attack()"
  2608. ]
  2609. },
  2610. {
  2611. "cell_type": "code",
  2612. "execution_count": 86,
  2613. "metadata": {},
  2614. "outputs": [
  2615. {
  2616. "name": "stdout",
  2617. "output_type": "stream",
  2618. "text": [
  2619. "[-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"
  2620. ]
  2621. }
  2622. ],
  2623. "source": [
  2624. "print(dbdd.u_original)"
  2625. ]
  2626. },
  2627. {
  2628. "cell_type": "code",
  2629. "execution_count": 87,
  2630. "metadata": {},
  2631. "outputs": [
  2632. {
  2633. "name": "stdout",
  2634. "output_type": "stream",
  2635. "text": [
  2636. "\u001b[1;37m integrate perfect hint \u001b[0m \u001b[0m \u001b[0m\n",
  2637. "Dimension of D: (141, 140)\n"
  2638. ]
  2639. }
  2640. ],
  2641. "source": [
  2642. "coeff = 2\n",
  2643. "v = vec(identity_matrix(n+m)[coeff])\n",
  2644. "l = dbdd.u_original[0,coeff]\n",
  2645. "dbdd.integrate_perfect_hint(v, l, estimate=False)\n",
  2646. "print(f'Dimension of D: {dbdd.D.dimensions()}')"
  2647. ]
  2648. },
  2649. {
  2650. "cell_type": "code",
  2651. "execution_count": 88,
  2652. "metadata": {},
  2653. "outputs": [
  2654. {
  2655. "name": "stdout",
  2656. "output_type": "stream",
  2657. "text": [
  2658. "Go... [140]\n",
  2659. "[141->140]\n",
  2660. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  2661. "\u001b[1;33m dim=140 \t δ=1.012476 \t β=42.87 \u001b[0m\n",
  2662. "\u001b[0m \u001b[0m\n",
  2663. "Dimension of D: (140, 140)\n"
  2664. ]
  2665. }
  2666. ],
  2667. "source": [
  2668. "_ = dbdd.estimate_attack()\n",
  2669. "print(f'Dimension of D: {dbdd.D.dimensions()}')"
  2670. ]
  2671. },
  2672. {
  2673. "cell_type": "code",
  2674. "execution_count": 89,
  2675. "metadata": {},
  2676. "outputs": [
  2677. {
  2678. "name": "stdout",
  2679. "output_type": "stream",
  2680. "text": [
  2681. "\u001b[1;37m integrate perfect hint \u001b[0m \u001b[0m \u001b[0m\n",
  2682. "Dimension of D: (140, 139)\n"
  2683. ]
  2684. }
  2685. ],
  2686. "source": [
  2687. "coeff0, coeff1 = 0,1\n",
  2688. "v = vec(identity_matrix(n+m)[coeff0])+vec(identity_matrix(n+m)[coeff1])\n",
  2689. "l = dbdd.u_original[0,coeff0]+dbdd.u_original[0,coeff1]\n",
  2690. "dbdd.integrate_perfect_hint(v, l, estimate=False)\n",
  2691. "print(f'Dimension of D: {dbdd.D.dimensions()}')"
  2692. ]
  2693. },
  2694. {
  2695. "cell_type": "code",
  2696. "execution_count": 90,
  2697. "metadata": {},
  2698. "outputs": [
  2699. {
  2700. "name": "stdout",
  2701. "output_type": "stream",
  2702. "text": [
  2703. "Go... [139]\n",
  2704. "[140->139]\n",
  2705. "\u001b[4;37m Attack Estimation \u001b[0m\n",
  2706. "\u001b[1;33m dim=139 \t δ=1.012676 \t β=40.13 \u001b[0m\n",
  2707. "\u001b[0m \u001b[0m\n",
  2708. "Dimension of D: (139, 139)\n"
  2709. ]
  2710. }
  2711. ],
  2712. "source": [
  2713. "_ = dbdd.estimate_attack()\n",
  2714. "print(f'Dimension of D: {dbdd.D.dimensions()}')"
  2715. ]
  2716. },
  2717. {
  2718. "cell_type": "code",
  2719. "execution_count": 91,
  2720. "metadata": {},
  2721. "outputs": [
  2722. {
  2723. "name": "stdout",
  2724. "output_type": "stream",
  2725. "text": [
  2726. "\u001b[4;37m Running the Attack \u001b[0m\n",
  2727. "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",
  2728. "\u001b[0m \u001b[0m\n"
  2729. ]
  2730. }
  2731. ],
  2732. "source": [
  2733. "beta, solution = dbdd.attack()"
  2734. ]
  2735. },
  2736. {
  2737. "cell_type": "code",
  2738. "execution_count": 181,
  2739. "metadata": {},
  2740. "outputs": [],
  2741. "source": [
  2742. "def one_experiment(n, nb_hints, dbdd_class, initialize_method, estimate=False, estimate_at_the_beginning=False, estimate_at_the_end=False):\n",
  2743. " m = n\n",
  2744. " q = 3301\n",
  2745. " D_s = build_centered_binomial_law(40)\n",
  2746. " D_e = build_centered_binomial_law(40)\n",
  2747. " d = m + n\n",
  2748. " timing = np.zeros(nb_hints+1)\n",
  2749. " \n",
  2750. " stime = time.time()\n",
  2751. " A, b, dbdd = initialize_method(dbdd_class, n, q, m, D_e, D_s, diag=False, verbosity=0)\n",
  2752. " if estimate_at_the_beginning:\n",
  2753. " _ = dbdd.estimate_attack(silent=True)\n",
  2754. " timing[0] = time.time()-stime\n",
  2755. " \n",
  2756. " for num_hint in range(nb_hints):\n",
  2757. " v = randv(m+n)\n",
  2758. " dbdd.integrate_perfect_hint(v, dbdd.leak(v), estimate=estimate)\n",
  2759. " timing[num_hint+1] = time.time()-stime\n",
  2760. " \n",
  2761. " if estimate_at_the_end and not estimate:\n",
  2762. " raise NotImplementedError()\n",
  2763. " # _ = dbdd.estimate_attack(silent=True)\n",
  2764. " \n",
  2765. " return timing"
  2766. ]
  2767. },
  2768. {
  2769. "cell_type": "code",
  2770. "execution_count": 193,
  2771. "metadata": {},
  2772. "outputs": [],
  2773. "source": [
  2774. "import time\n",
  2775. "def many_experiments(nb_experiments, n, nb_max_hints, dbdd_class, initialize_method, estimate=False, estimate_at_the_beginning=False):\n",
  2776. " timing = np.zeros(nb_max_hints+1)\n",
  2777. "\n",
  2778. " for _ in range(nb_experiments):\n",
  2779. " timing += one_experiment(n, nb_max_hints, dbdd_class, initialize_method, estimate=estimate, estimate_at_the_beginning=estimate_at_the_beginning)\n",
  2780. "\n",
  2781. " timing /= nb_experiments\n",
  2782. " return timing"
  2783. ]
  2784. },
  2785. {
  2786. "cell_type": "code",
  2787. "execution_count": 150,
  2788. "metadata": {},
  2789. "outputs": [
  2790. {
  2791. "name": "stdout",
  2792. "output_type": "stream",
  2793. "text": [
  2794. "29"
  2795. ]
  2796. }
  2797. ],
  2798. "source": [
  2799. "nb_experiments = 2\n",
  2800. "nb_hints_list = list(range(30))\n",
  2801. "timing = []\n",
  2802. "\n",
  2803. "import time\n",
  2804. "for nb_hints in nb_hints_list:\n",
  2805. " print(f'\\r{nb_hints}', end='')\n",
  2806. " start_time = time.time()\n",
  2807. " for _ in range(nb_experiments):\n",
  2808. " one_experiment(70, nb_hints, DBDD, initialize_from_LWE_instance)\n",
  2809. " timing.append((time.time() - start_time)/nb_experiments)"
  2810. ]
  2811. },
  2812. {
  2813. "cell_type": "code",
  2814. "execution_count": 160,
  2815. "metadata": {},
  2816. "outputs": [
  2817. {
  2818. "data": {
  2819. "image/png": "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\n",
  2820. "text/plain": [
  2821. "<Figure size 432x288 with 1 Axes>"
  2822. ]
  2823. },
  2824. "metadata": {},
  2825. "output_type": "display_data"
  2826. }
  2827. ],
  2828. "source": [
  2829. "import matplotlib.pyplot as plt\n",
  2830. "plt.plot(nb_hints_list, timing)\n",
  2831. "plt.xlabel('Number of hints')\n",
  2832. "plt.ylabel('Time (in s)')\n",
  2833. "plt.title('Speed of Improved Leaky-LWE-Estimator')\n",
  2834. "plt.show()\n",
  2835. "None"
  2836. ]
  2837. },
  2838. {
  2839. "cell_type": "code",
  2840. "execution_count": 226,
  2841. "metadata": {},
  2842. "outputs": [],
  2843. "source": [
  2844. "nb_max_hints = 45\n",
  2845. "nb_experiments = 2\n",
  2846. "n = 30"
  2847. ]
  2848. },
  2849. {
  2850. "cell_type": "code",
  2851. "execution_count": 227,
  2852. "metadata": {},
  2853. "outputs": [],
  2854. "source": [
  2855. "timing1 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=False, estimate_at_the_beginning=False) \n",
  2856. "timing2 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=True, estimate_at_the_beginning=True) "
  2857. ]
  2858. },
  2859. {
  2860. "cell_type": "code",
  2861. "execution_count": 228,
  2862. "metadata": {},
  2863. "outputs": [],
  2864. "source": [
  2865. "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",
  2866. "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) "
  2867. ]
  2868. },
  2869. {
  2870. "cell_type": "code",
  2871. "execution_count": 229,
  2872. "metadata": {},
  2873. "outputs": [
  2874. {
  2875. "data": {
  2876. "image/png": "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\n",
  2877. "text/plain": [
  2878. "<Figure size 432x288 with 1 Axes>"
  2879. ]
  2880. },
  2881. "metadata": {},
  2882. "output_type": "display_data"
  2883. }
  2884. ],
  2885. "source": [
  2886. "import matplotlib.pyplot as plt\n",
  2887. "plt.plot(timing1, label='Improved (never estimate)')\n",
  2888. "plt.plot(timing2, label='Improved (always estimate)')\n",
  2889. "plt.plot(timing3, label='Official (never estimate)')\n",
  2890. "plt.plot(timing4, label='Official (always estimate)')\n",
  2891. "plt.legend()\n",
  2892. "plt.xlabel('Number of perfect hints')\n",
  2893. "plt.ylabel('Time (in s)')\n",
  2894. "#plt.yscale('log')\n",
  2895. "plt.title(f'Speed of Improved Leaky-LWE-Estimator (n={n})')\n",
  2896. "plt.savefig('comparison-speed.png')\n",
  2897. "plt.show()\n",
  2898. "None"
  2899. ]
  2900. },
  2901. {
  2902. "cell_type": "code",
  2903. "execution_count": 131,
  2904. "metadata": {},
  2905. "outputs": [],
  2906. "source": [
  2907. "one_experiment(70, 2, DBDD, initialize_from_LWE_instance)"
  2908. ]
  2909. },
  2910. {
  2911. "cell_type": "code",
  2912. "execution_count": 224,
  2913. "metadata": {},
  2914. "outputs": [],
  2915. "source": [
  2916. "nb_max_hints = 7\n",
  2917. "nb_experiments = 10\n",
  2918. "n = 5\n",
  2919. "timing1 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=False, estimate_at_the_beginning=False) \n",
  2920. "timing2 = many_experiments(nb_experiments, n, nb_max_hints, DBDD, initialize_from_LWE_instance, estimate=True, estimate_at_the_beginning=True) \n",
  2921. "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",
  2922. "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)"
  2923. ]
  2924. },
  2925. {
  2926. "cell_type": "code",
  2927. "execution_count": 225,
  2928. "metadata": {},
  2929. "outputs": [
  2930. {
  2931. "data": {
  2932. "image/png": "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\n",
  2933. "text/plain": [
  2934. "<Figure size 432x288 with 1 Axes>"
  2935. ]
  2936. },
  2937. "metadata": {},
  2938. "output_type": "display_data"
  2939. }
  2940. ],
  2941. "source": [
  2942. "import matplotlib.pyplot as plt\n",
  2943. "plt.plot(timing1, label='Improved (never estimate)')\n",
  2944. "plt.plot(timing2, label='Improved (always estimate)')\n",
  2945. "plt.plot(timing3, label='Official (never estimate)')\n",
  2946. "plt.plot(timing4, label='Official (always estimate)')\n",
  2947. "plt.legend()\n",
  2948. "plt.xlabel('Number of perfect hints')\n",
  2949. "plt.ylabel('Time (in s)')\n",
  2950. "#plt.yscale('log')\n",
  2951. "plt.title(f'Speed of Improved Leaky-LWE-Estimator (n={n})')\n",
  2952. "plt.show()\n",
  2953. "None"
  2954. ]
  2955. },
  2956. {
  2957. "cell_type": "code",
  2958. "execution_count": null,
  2959. "metadata": {},
  2960. "outputs": [],
  2961. "source": []
  2962. },
  2963. {
  2964. "cell_type": "markdown",
  2965. "metadata": {},
  2966. "source": [
  2967. "## Validation Tests"
  2968. ]
  2969. },
  2970. {
  2971. "cell_type": "code",
  2972. "execution_count": 271,
  2973. "metadata": {},
  2974. "outputs": [
  2975. {
  2976. "name": "stdout",
  2977. "output_type": "stream",
  2978. "text": [
  2979. "\u001b[3;34m Number of threads : 1 \u001b[0m\n",
  2980. "\u001b[3;34m Number of Samples : 5 \u001b[0m\n",
  2981. "\u001b[4;37m Validation tests \u001b[0m\n",
  2982. "\n",
  2983. " \n",
  2984. " None\n",
  2985. "hints,\t real,\t pred_full, \t pred_light,\n"
  2986. ]
  2987. },
  2988. {
  2989. "name": "stderr",
  2990. "output_type": "stream",
  2991. "text": [
  2992. "Process Process-88:\n",
  2993. "Traceback (most recent call last):\n",
  2994. " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 297, in _bootstrap\n",
  2995. " self.run()\n",
  2996. " File \"/opt/sagemath-9.0/local/lib/python3.7/multiprocessing/process.py\", line 99, in run\n",
  2997. " self._target(*self._args, **self._kwargs)\n",
  2998. " 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",
  2999. " r = f(i + 2**16 * trial, args)\n"
  3000. ]
  3001. },
  3002. {
  3003. "ename": "KeyboardInterrupt",
  3004. "evalue": "",
  3005. "output_type": "error",
  3006. "traceback": [
  3007. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  3008. "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
  3009. "\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",
  3010. "\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",
  3011. "\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",
  3012. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n",
  3013. "\u001b[0;32m<string>\u001b[0m in \u001b[0;36mvalidation_prediction\u001b[0;34m(N_tests, N_hints, T_hints)\u001b[0m\n",
  3014. "\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",
  3015. "\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",
  3016. "\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",
  3017. "\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",
  3018. "\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",
  3019. "\u001b[0;32msrc/cysignals/signals.pyx\u001b[0m in \u001b[0;36mcysignals.signals.python_check_interrupt\u001b[0;34m()\u001b[0m\n",
  3020. "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
  3021. ]
  3022. },
  3023. {
  3024. "name": "stderr",
  3025. "output_type": "stream",
  3026. "text": [
  3027. " File \"<string>\", line 42, in one_experiment\n",
  3028. " File \"<string>\", line 41, in initialize_from_LWE_instance\n",
  3029. " File \"<string>\", line 44, in __init__\n",
  3030. " File \"<string>\", line 264, in estimate_attack\n",
  3031. " File \"<string>\", line 51, in decorated\n",
  3032. " File \"<string>\", line 64, in volumes\n",
  3033. " File \"<string>\", line 248, in degen_logdet\n",
  3034. " File \"sage/matrix/matrix2.pyx\", line 13219, in sage.matrix.matrix2.Matrix.norm (build/cythonized/sage/matrix/matrix2.c:89623)\n",
  3035. " return max(S.list()).real().sqrt()\n",
  3036. " File \"sage/matrix/matrix0.pyx\", line 160, in sage.matrix.matrix0.Matrix.list (build/cythonized/sage/matrix/matrix0.c:4260)\n",
  3037. " return list(self._list())\n",
  3038. " File \"sage/matrix/matrix0.pyx\", line 212, in sage.matrix.matrix0.Matrix._list (build/cythonized/sage/matrix/matrix0.c:4410)\n",
  3039. " x.append(self.get_unsafe(i, j))\n",
  3040. " 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",
  3041. " return self._sage_dtype(cnumpy.PyArray_GETITEM(self._matrix_numpy,\n",
  3042. " 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",
  3043. " return Parent.__call__(self, x)\n",
  3044. " File \"sage/structure/parent.pyx\", line 900, in sage.structure.parent.Parent.__call__ (build/cythonized/sage/structure/parent.c:9218)\n",
  3045. " return mor._call_(x)\n",
  3046. " File \"sage/categories/map.pyx\", line 1694, in sage.categories.map.FormalCompositeMap._call_ (build/cythonized/sage/categories/map.c:11607)\n",
  3047. " x = f._call_(x)\n",
  3048. " 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",
  3049. " cpdef Element _call_(self, x):\n",
  3050. " 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",
  3051. " return C._element_constructor(x)\n",
  3052. " File \"/opt/sagemath-9.0/local/lib/python3.7/site-packages/sage/rings/complex_field.py\", line 429, in _element_constructor_\n",
  3053. " return ComplexNumber(self, x)\n",
  3054. " File \"src/cysignals/signals.pyx\", line 320, in cysignals.signals.python_check_interrupt\n",
  3055. "KeyboardInterrupt\n"
  3056. ]
  3057. }
  3058. ],
  3059. "source": [
  3060. "load('prediction_verifications.sage')"
  3061. ]
  3062. },
  3063. {
  3064. "cell_type": "code",
  3065. "execution_count": 272,
  3066. "metadata": {},
  3067. "outputs": [
  3068. {
  3069. "name": "stdout",
  3070. "output_type": "stream",
  3071. "text": [
  3072. "[ 0 0 0 0 0 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",
  3073. "[ 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",
  3074. "[ 0 0 0 0 0 0 0 0 0 0 0 0 0 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"
  3075. ]
  3076. },
  3077. {
  3078. "data": {
  3079. "text/plain": [
  3080. "(37, 36.6627779805685, 35.9333472121491)"
  3081. ]
  3082. },
  3083. "execution_count": 272,
  3084. "metadata": {},
  3085. "output_type": "execute_result"
  3086. }
  3087. ],
  3088. "source": [
  3089. "one_experiment(0, (3, \"Q-Modular\"))"
  3090. ]
  3091. },
  3092. {
  3093. "cell_type": "code",
  3094. "execution_count": null,
  3095. "metadata": {},
  3096. "outputs": [],
  3097. "source": []
  3098. }
  3099. ],
  3100. "metadata": {
  3101. "kernelspec": {
  3102. "display_name": "SageMath 9.0",
  3103. "language": "sage",
  3104. "name": "sagemath"
  3105. },
  3106. "language_info": {
  3107. "codemirror_mode": {
  3108. "name": "ipython",
  3109. "version": 3
  3110. },
  3111. "file_extension": ".py",
  3112. "mimetype": "text/x-python",
  3113. "name": "python",
  3114. "nbconvert_exporter": "python",
  3115. "pygments_lexer": "ipython3",
  3116. "version": "3.7.3"
  3117. }
  3118. },
  3119. "nbformat": 4,
  3120. "nbformat_minor": 2
  3121. }