|
399 | 399 | "cell_type": "markdown",
|
400 | 400 | "metadata": {},
|
401 | 401 | "source": [
|
402 |
| - "\n", |
403 | 402 | "# Tradeoff accuracy vs time\n",
|
404 | 403 | "\n",
|
405 | 404 | "The pipeline for computing the eigenvalues and eigenvectors of a symmetric matrix using our proposed method is as follows:\n",
|
|
757 | 756 | "<!--  -->"
|
758 | 757 | ]
|
759 | 758 | },
|
| 759 | + { |
| 760 | + "cell_type": "markdown", |
| 761 | + "metadata": {}, |
| 762 | + "source": [ |
| 763 | + "# A note on the code in C++\n", |
| 764 | + "As anticipated in the `README.md` file, a few functions have been written in `C++` and have then been exposed to `Python` using `pybind11`.\n", |
| 765 | + "The reason for this choice is the following one: either compiling them with `numba` offered no major performance advantage, or it was simply not possible as a result of the fact that some types that we used (e.g. `SciPy`'s sparse matrices) are not compatible with `numba`.\n", |
| 766 | + "\n", |
| 767 | + "The cell below provides a comparison of the execution time of the original `Python` implementation and the `C++` one." |
| 768 | + ] |
| 769 | + }, |
| 770 | + { |
| 771 | + "cell_type": "code", |
| 772 | + "execution_count": null, |
| 773 | + "metadata": {}, |
| 774 | + "outputs": [], |
| 775 | + "source": [ |
| 776 | + "from pyclassify.cxx_utils import secular_solver_cxx\n", |
| 777 | + "from pyclassify.zero_finder import secular_solver_python\n", |
| 778 | + "\n", |
| 779 | + "seed = 2206\n", |
| 780 | + "np.seed(seed)\n", |
| 781 | + "\n", |
| 782 | + "n = 1000\n", |
| 783 | + "d = np.arange(n)\n", |
| 784 | + "rho = 2.\n", |
| 785 | + "D = np.diag(d)\n", |
| 786 | + "v = np.random.rand(n)\n", |
| 787 | + "\n", |
| 788 | + "indices = range(len(d))\n", |
| 789 | + "rk_1_update = rho * np.outer(v, v)\n", |
| 790 | + "L = D + rk_1_update\n", |
| 791 | + "\n", |
| 792 | + "begin_cxx = time()\n", |
| 793 | + "computed_eigs_cxx, _, __ = secular_solver_cxx(rho, d, v, indices)\n", |
| 794 | + "end_cxx = time()\n", |
| 795 | + "duration_cxx = end_cxx - begin_cxx\n", |
| 796 | + "\n", |
| 797 | + "begin_python = time()\n", |
| 798 | + "computed_eigs_python = secular_solver_python(rho, d, v) \n", |
| 799 | + "end_python = time()\n", |
| 800 | + "duration_python = end_python - begin_python\n", |
| 801 | + "\n", |
| 802 | + "print(f'Speedup: {duration_python/duration_cxx}')\n", |
| 803 | + "\n", |
| 804 | + "exact_eigs, _ = np.linalg.eig(L)\n", |
| 805 | + "exact_eigs = np.sort(exact_eigs)\n", |
| 806 | + "\n", |
| 807 | + "for i in range(len(exact_eigs)):\n", |
| 808 | + " # Assert that the C++ eigenvalues are correct\n", |
| 809 | + " assert (\n", |
| 810 | + " np.abs(computed_eigs_cxx[i] - exact_eigs[i]) < 1e-8\n", |
| 811 | + " ), \"Error. The eigenvalues were not computed correctly.\"\n", |
| 812 | + " # Also assert that they are close to the Python ones\n", |
| 813 | + " assert (\n", |
| 814 | + " np.abs(computed_eigs_cxx[i] - computed_eigs_python[i]) < 1e-8\n", |
| 815 | + " ), \"Error. The eigenvalues were not computed correctly.\"" |
| 816 | + ] |
| 817 | + }, |
760 | 818 | {
|
761 | 819 | "cell_type": "markdown",
|
762 | 820 | "metadata": {
|
|
781 | 839 | "\n",
|
782 | 840 | "[7] [Arbenz, Peter. Lecture Notes on Solving Large Scale Eigenvalue Problems - Chapter 5-6. Computer Science Department, ETH Zürich, Spring semester 2016.](https://sissa-my.sharepoint.com/my?FolderCTID=0x012000B3941AA86D63224F9CC9A5B1FEDCCF3B&id=%2Fpersonal%2Fglicausi%5Fsissa%5Fit%2FDocuments%2FPhD%2FDevelopment%20Tools%20for%20Scientific%20Computing%20%2D%20Project%20material%20and%20references%2Fchapters5%2D6%2Epdf&parent=%2Fpersonal%2Fglicausi%5Fsissa%5Fit%2FDocuments%2FPhD%2FDevelopment%20Tools%20for%20Scientific%20Computing%20%2D%20Project%20material%20and%20references)"
|
783 | 841 | ]
|
784 |
| - }, |
785 |
| - { |
786 |
| - "cell_type": "markdown", |
787 |
| - "metadata": {}, |
788 |
| - "source": [] |
789 | 842 | }
|
790 | 843 | ],
|
791 | 844 | "metadata": {
|
|
0 commit comments