Sometimes, when you are writing a statistics or a math article, you must go through a tedious process of typing and testing numerous lines of text until your \(LaTeX\) code works. This can be especially boring when dealing with long matrices. If you want to improve your productivity, automating this process comes in very handy, and Python is particularly useful for that.
Functions for matrices and determinants
The functions matrix2latex and det2latex return an indented \(LaTeX\) string that can be copied or rendered in your math article.
The parameter INDENT_SPACES controls the number of indentation spaces.
Code
import numpy as npINDENT_SPACES =3def indent(num_indent=1):""" Number of indentation spaces """return num_indent * INDENT_SPACES *" "def matrix2latex(matrix):""" Convert numpy array to latex code as a matrix """ left_latex =r"\left("+"\n"+ indent(1) +r"\begin{array}" right_latex = indent(1) +r"\end{array}"+"\n"+r"\right)" m_cols = matrix.shape[1] array_cols ="{"+"r"* m_cols +"}\n" elements_latex =""for row in matrix: elements_latex =\ elements_latex + indent(2) +" & ".join([str(x) for x in row]) +\r" \\ "+"\n" latex = left_latex + array_cols + elements_latex + right_latexreturnf"$$\n{latex}\n$$"def det2latex(matrix):""" Convert numpy array to latex code as a determinant """ left_latex =r"\begin{vmatrix}"+"\n" right_latex =r"\end{vmatrix}" m_cols = matrix.shape[1] elements_latex =""for row in matrix: elements_latex =\ elements_latex + indent(1) +" & ".join([str(x) for x in row]) +\r" \\ "+"\n" latex = left_latex + elements_latex + right_latexreturnf"$$\n{latex}\n$$"
Output string
With the NumPy function np.eye, we can create an identity matrix of the desired dimensions, and this seems to be a good way to test our functions.
If you are working within a Jupyter notebook you can render a latex string with the aid of the Math function included in the IPython library, which can be imported with:
Code
from IPython.display import Math
But if you are coding a Python chunk in a Quarto file on RStudio, you need to add the option #| output: asis at the top of the code chunk. This option controls how the output is rendered in the final document.
Upper Triangular Matrix: In an upper triangular matrix, all elements below the main diagonal (elements that lie on or below the main diagonal) are zeros.
Lower Triangular Matrix: In a lower triangular matrix, all elements above the main diagonal (elements that lie on or above the main diagonal) are zeros
Code
def up_triangular_matrix(n):""" Upper Triangular matrix filled with ones and zeroes """return np.fromfunction(lambda i, j: 1* np.less_equal(i , j), shape=(n, n), dtype=int)
Lower Triangular Matrix: In a lower triangular matrix, all elements above the main diagonal (elements that lie on or above the main diagonal) are zeros
Code
def lw_triangular_matrix(n):""" Lower Triangular matrix filled with ones and zeroes """return np.fromfunction(lambda i, j: 1* np.greater_equal(i , j), shape=(n, n), dtype=int)
---title: Convert Numpy array to LaTeXdescription: LaTeX matrices and determinants from numpy arraysauthor: 'Enrique Pérez Herrero'date: '08-02-2023'editor: sourceimage: 'theta3x3matrix.png'draft: falsecategories: - python - numpy - latex---![Sierra de las Nieves (Málaga)](20180104_134329.jpg)# Convert Numpy array to $LaTeX$Sometimes, when you are writing a statistics or a math article, you must gothrough a tedious process of typing and testing numerous lines of text untilyour $LaTeX$ code works. This can be especially boring when dealing with longmatrices. If you want to improve your productivity, automating this processcomes in very handy, and Python is particularly useful for that.## Functions for matrices and determinantsThe functions `matrix2latex` and `det2latex` return an indented $LaTeX$ stringthat can be copied or rendered in your math article.The parameter `INDENT_SPACES` controls the number of indentation spaces.```{python}#| label: latex_functionsimport numpy as npINDENT_SPACES =3def indent(num_indent=1):""" Number of indentation spaces """return num_indent * INDENT_SPACES *" "def matrix2latex(matrix):""" Convert numpy array to latex code as a matrix """ left_latex =r"\left("+"\n"+ indent(1) +r"\begin{array}" right_latex = indent(1) +r"\end{array}"+"\n"+r"\right)" m_cols = matrix.shape[1] array_cols ="{"+"r"* m_cols +"}\n" elements_latex =""for row in matrix: elements_latex =\ elements_latex + indent(2) +" & ".join([str(x) for x in row]) +\r" \\ "+"\n" latex = left_latex + array_cols + elements_latex + right_latexreturnf"$$\n{latex}\n$$"def det2latex(matrix):""" Convert numpy array to latex code as a determinant """ left_latex =r"\begin{vmatrix}"+"\n" right_latex =r"\end{vmatrix}" m_cols = matrix.shape[1] elements_latex =""for row in matrix: elements_latex =\ elements_latex + indent(1) +" & ".join([str(x) for x in row]) +\r" \\ "+"\n" latex = left_latex + elements_latex + right_latexreturnf"$$\n{latex}\n$$"```### Output stringWith the NumPy function `np.eye`, we can create an identity matrix of thedesired dimensions, and this seems to be a good way to test our functions.```{python}print(matrix2latex(np.eye(3, dtype=int)))```## Rendering the output in a documentIf you are working within a [Jupyter](https://jupyter.org/) notebook you canrender a latex string with the aid of the `Math` function included in the`IPython` library, which can be imported with:```{python}#| eval: falsefrom IPython.display import Math```But if you are coding a `Python` chunk in a `Quarto` file on RStudio, you needto add the option `#| output: asis` at the top of the code chunk. This optioncontrols how the output is rendered in the final document.```{python}#| label: identity_det#| output: asisprint(det2latex(np.eye(3, dtype=int)))``````{python}#| label: identity_matrix#| output: asis# Identity 4x4 matrixidentity_4 = np.eye(4, dtype=int)identity_4_latex =r"$$I_4 = "+f"{matrix2latex(identity_4)}"[2:]print(identity_4_latex)```## Rendering the output in a fileThe $LaTeX$ string can be rendered and saved into a file with the aid of thefollowing function, based on the library `sympy`.```{python}#| eval: falsefrom sympy import previewdef latex2png(latex, filename, fontsize=300):""" Render latex code to png image """return preview(latex, viewer='file', filename=filename, euler=False, dvioptions=['-D', f'{str(fontsize)}'])```## Other automated matrices### Matrices with numbered elements```{python}def element_matrix(n, notation=r"x"):""" Matrix with algebraic notation elements """ vec_function =\ np.vectorize(lambda i, j: notation +"_{"+f"{i +1}{j +1}"+"}")return np.fromfunction(vec_function, shape=(n, n), dtype=int)``````{python}#| label: element_matrix_example#| output: asisprint(matrix2latex(element_matrix(5, notation=r"\theta")))```### Triangular matrices* Upper Triangular Matrix: In an upper triangular matrix, all elements below themain diagonal (elements that lie on or below the main diagonal) are zeros.* Lower Triangular Matrix: In a lower triangular matrix, all elements above the main diagonal (elements that lie on or above the main diagonal) are zeros```{python}def up_triangular_matrix(n):""" Upper Triangular matrix filled with ones and zeroes """return np.fromfunction(lambda i, j: 1* np.less_equal(i , j), shape=(n, n), dtype=int)```* Lower Triangular Matrix: In a lower triangular matrix, all elements above the main diagonal (elements that lie on or above the main diagonal) are zeros```{python}def lw_triangular_matrix(n):""" Lower Triangular matrix filled with ones and zeroes """return np.fromfunction(lambda i, j: 1* np.greater_equal(i , j), shape=(n, n), dtype=int)``````{python}#| label: upper_matrix_example#| output: asisprint(matrix2latex(up_triangular_matrix(5)))```