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 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 generate an indented string that can be copied or directly rendered in your math article.
The INDENT_SPACES parameter specifies the number of spaces used for indentation.
Code
import numpy as npINDENT_SPACES =3def indent(num_indent=1):""" Number of spaces for indentation """return num_indent * INDENT_SPACES *" "def matrix2latex(matrix):""" Convert a 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 a 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
Using the NumPy function np.eye, we can create an identity matrix of the desired dimensions, making it a convenient tool for testing our functions.
If you are working in a Jupyter notebook, you can render a string using the Math function from the IPython library, which can be imported as follows:
Code
from IPython.display import Math
If you are writing a Python chunk in a Quarto file in RStudio, you need to include the option #| output: asis at the top of the code chunk. This option determines how the output is rendered in the final document.
Upper Triangular Matrix: In an upper triangular matrix, all elements below the main diagonal are zero.
Code
def up_triangular_matrix(n):""" Upper Triangular matrix filled with ones and zeros """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 are zero.
Code
def lw_triangular_matrix(n):""" Lower Triangular matrix filled with ones and zeros """return np.fromfunction(lambda i, j: 1* np.greater_equal(i , j), shape=(n, n), dtype=int)
Code
print(matrix2latex(up_triangular_matrix(5)))
Source Code
---title: Convert a 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---# 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 code works. This can be especially boring when dealing with long matrices.If you want to improve your productivity, automating this process comes in veryhandy, and [Python](https://www.python.org/) is particularly useful for that.## Functions for matrices and determinantsThe functions `matrix2latex` and `det2latex` generate an indented $LaTeX$ stringthat can be copied or directly rendered in your math article.The `INDENT_SPACES` parameter specifies the number of spaces used forindentation.```{python}#| label: latex_functionsimport numpy as npINDENT_SPACES =3def indent(num_indent=1):""" Number of spaces for indentation """return num_indent * INDENT_SPACES *" "def matrix2latex(matrix):""" Convert a 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 a 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 stringUsing the [NumPy](https://numpy.org/) function `np.eye`, we can create anidentity matrix of the desired dimensions, making it a convenient tool fortesting our functions.```{python}print(matrix2latex(np.eye(3, dtype=int)))```## Rendering output in a documentIf you are working in a [Jupyter](https://jupyter.org/) notebook, you can rendera $LaTeX$ string using the `Math` function from the `IPython` library, which canbe imported as follows:```{python}#| eval: falsefrom IPython.display import Math```If you are writing a `Python` chunk in a `Quarto` file in[RStudio](https://posit.co/download/rstudio-desktop/), you need to include theoption `#| output: asis` at the top of the code chunk. This option determineshow 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 to a fileThe $LaTeX$ string can be rendered and saved to a file using thefollowing function, which is based on the `SymPy` library.```{python}#| eval: falsefrom sympy import previewdef latex2png(latex, filename, fontsize=300):""" Render LaTeX code to a PNG image """return preview(latex, viewer='file', filename=filename, euler=False, dvioptions=['-D', f'{str(fontsize)}'])```## Other types of automated matrices### Matrices with numbered elements```{python}def element_matrix(n, notation=r"x"):""" Matrix with elements in algebraic notation """ 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 are zero.```{python}def up_triangular_matrix(n):""" Upper Triangular matrix filled with ones and zeros """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 are zero.```{python}def lw_triangular_matrix(n):""" Lower Triangular matrix filled with ones and zeros """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)))```