When building pharmacometric or systems pharmacology models, it is often useful to share the mathematical form of the model, either for publication, collaboration, or documentation. However, transcribing equations by hand is error-prone and time-consuming.
The Pumas model macros capture enough structured information so that Latexify can automatically generate LaTeX (or MathJax) representations of a model’s parameters and equations. The equation can then be copied, adapted, or directly rendered in any environment.
This document walks through the Warfarin PKPD model below, showing how to:
Extract individual blocks (like the @param or @dynamics blocks).
Configure the look-and-feel of the generated LaTeX.
Stitch multiple blocks together into a single model representation.
2 Defining the Warfarin PKPD Model
First, the Warfarin model is restated. Ensure that Pumas is loaded, and then define the model:
Latexify comes with Pumas so it is not necessary to install it separately. It can be loaded with:
usingPumas.Latexify
3.2 Latexifying Individual Blocks
Each Pumas model is composed of blocks that capture different stages of the model definition (@param, @random, @pre, @init, @dynamics, @derived, etc.). LaTeX can be generated for each block independently.
For instance, LaTeX for the parameter block can be generated as follows:
And the same can be done for :pre, :init, :vars, :dynamics, and :derived. The name of each block corresponds exactly to the model macro blocks.
3.3 Rendering and Viewing the Equations
3.3.0.1 In a Julia REPL or VSCode
In the REPL, calling latexify(...) directly will show the LaTeX string.
In VSCode, the built-in plot pane or an extension can be used to render LaTeX. Alternatively, println(latexify(...)) can be called to see the code, then copy-paste into a LaTeX document or a Markdown cell with MathJax.
Example in a notebook cell:
latexify(warfarin_pkpd_model, :dynamics)
This will produce a nicely rendered system of ODEs corresponding to the @dynamics block.
Tip
The rendered output in the VSCode plot or in the rendered notebook will be either a CHTML image or an SVG image, depending on the MathJax preferences set by the user. By right-clicking on the image, various options are available to copy the underlying LaTeX code in different formats. The MathML format, once copied, can be directly pasted into a Microsoft Word document, where it will render as an Equation Editor object.
If the output is rendered as an SVG image, it can be saved similarly to a plot by using the “Julia: save plot” icon located at the top of the plot pane. This feature is particularly useful for creating presentations in PowerPoint, as it allows for easy integration of high-quality images.
In cases where the “Julia: save plot” icon does not function, it indicates that the output is being rendered in CHTML format. To change this setting, right-click on the rendered image, navigate to Math Settings, then Math Renderer, and select SVG. This setting is persistent, so it does not need to be adjusted frequently.
3.4 Customizing the Output
Latexify provides additional keyword arguments to tweak how the equations look.
An example customization is shown below:
latexify(warfarin_pkpd_model, :pre; index =:bracket, snakecase =true)
3.5 Stitching Multiple Blocks Together
A common desire is to produce a single LaTeX document that shows all the relevant equations. Because latexify(model, blockname) returns a LaTeXString, they can be easily combined. For example:
# Collect the blocks needed:blocks = [:param, :random, :pre, :dynamics, :derived]# Map each block to its latexify result, then joinmodel_representation = Latexify.LaTeXString(join( [latexify(warfarin_pkpd_model, block, index =:bracket, snakecase =true) for block in blocks ],"\n\n", # separate by new lines ),);
This will produce a single LaTeX string that can be copied and pasted into a LaTeX document or a Markdown cell with MathJax.
The model_representation can be wrapped in sections or environment tags:
tex_param =latexify(warfarin_pkpd_model, :param; index =:bracket, snakecase =true)tex_random =latexify(warfarin_pkpd_model, :random; index =:bracket, snakecase =true)tex_pre =latexify(warfarin_pkpd_model, :pre; index =:bracket, snakecase =true)tex_dynamics =latexify(warfarin_pkpd_model, :dynamics; index =:bracket, snakecase =true)tex_derived =latexify(warfarin_pkpd_model, :derived; index =:bracket, snakecase =true)println(""" ### Warfarin Model: Parameter Block$tex_param ### Random Effects$tex_random ### Pre Block$tex_pre ### Dynamics Block$tex_dynamics ### Derived Block$tex_derived """)
3.5.1 Warfarin Model: Parameter Block
3.5.2 Random Effects
3.5.3 Pre Block
3.5.4 Dynamics Block
3.5.5 Derived Block
When generating a true .tex file, it may be necessary to escape some backslashes appropriately or place them in a valid LaTeX environment (e.g., \begin{document} ... \end{document}).
3.6 A Example in Action
Here’s a compact snippet that:
Defines the Warfarin model (using the code above).
latexifys the :dynamics block.
Renders it in a Quarto notebook:
dynamics_equations =latexify(warfarin_pkpd_model, :dynamics)# In a notebook, just do:dynamics_equations
This will display nicely typeset ODEs for Depot, Central, and Turnover, including the definitions of the rates.
3.7 Summary and Next Steps
Latexify offers a powerful way to automatically generate mathematical expressions from Pumas models.
Focus can remain on model building while letting Latexify handle the tedious transcription.
Different blocks of the model (parameters, random effects, pre, init, dynamics, derived, etc.) can be latexified individually or combined into a single string.
Customization options (keyword arguments) allow control over styles.
For more advanced usage, refer to the Latexify Documentation for formatting and environment options.