korsbo / Latexify.jl

Convert julia objects to LaTeX equations, arrays or other environments.
MIT License
563 stars 60 forks source link

UTF modifiers causing latexification issues #206

Closed finmod closed 2 years ago

finmod commented 2 years ago

@korsbo The issue here is that variables written in Latex as $ \boldsymbol{\omega}(t), \boldsymbol{\lambda}(t), \mathbf{d}(t), \mathbf{y}_{\boldsymbol{e}}(t), \mathbf{u}(t), \mathbf{y}_{\boldsymbol{d}}(t) $ are not rendered accurately in MTK coding and equations(). In particular, letter subscripts are not supported whereas numeral subscripts are.

Also, there is the question of a variable $\boldsymbol{\pi}_{\boldsymbol{e} }$ not being confused with the numerical pie

korsbo commented 2 years ago

closed by #208

finmod commented 2 years ago

There remains a small issue with subscripted variables. In printing out this example, you can see that subscripted quantities are represented properly some of the times but not all the time (e.g. y_d and y_e)

 ModelingToolkit.@parameters begin

      η=500
      C=0.33
      b=0.135
      α=0.025
      β=0.02
      δ=0.05
      r=0.03

      ϕ₀=0.0401
      ϕ₁=6.41e-05

      k₀=-0.0065
      k₁=-5.0
      k₂=20
      ηu=0.2
      u_b=0.9 

      m=1.2
      γ=0.4
      f_d=0.1

      η₁=0.8
      η₂=0.2
      η₃=0.7
      ηₑ=0.8 

      θ₁=0.9 
      θ₂=0.8 
      θ₃=-5.0
      e₁=0.0
      g₂= α + β
end    

@variables begin
      t
      ω(t) = 0.9
      λ(t) = 0.9
      d(t) = 0.5
      y_e(t) = 0.9
      u(t) = 0.8
      y_d(t) = 0.9

      ν(t) = 3.0
      φ(t)
      ι(t)
      κ(t)
      p_e(t)
      θ(t) 
      g(t) 
end

Dₜ = Differential(t)
tmax = 25.0                         # 25 years

# Behavioural equations

p_e = (t, ω, y_e, d) ->           y_e*(1 - ω) - r*d
ν  = (t, ω) ->                    (1/C)*((1 -  ω)/b)^(-1/η)
φ  = (t, λ) ->                    -ϕ₀ + ϕ₁/((1 - λ)^2)
ι  = (t, ω, y_d, y_e) ->          η₁*(m*ω − 1) + η₂*(y_d - y_e)
κ  = (t, p_e, u) ->               k₀ + exp(k₁+ k₂*p_e(t, ω, y_e, d)) + ηu*(u - u_b)
θ  = (t, ω) ->                    θ₁/((1 + θ₂*exp(θ₃*ω))^(1/η₂))
g  = (t, y_d, y_e) ->             (f_d*(g₂ + η₃) + 1.0)*(y_e*g₂ +ηₑ*(y_d - y_e)) + η₃*(y_d - 1)

sfc = [
      Dₜ(ω)  ~ ω*(η/(1 + η))*(φ(t,λ) - α - (1 - γ)*ι(t, ω, y_d, y_e))
      Dₜ(λ)  ~ λ*(g(t, y_d, y_e) - α - β)
      Dₜ(d) ~ d*(r - g(t, y_d, y_e) - ι(t, ω, y_d, y_e)) + ω - θ(t, ω)
      Dₜ(y_e) ~ y_e*(g₂ - g(t, y_d, y_e)) + ηₑ*(y_d - y_e)
      Dₜ(u)  ~ u*(g(t, y_d, y_e) - κ(t, p_e, u)/ν(t, ω) + δ)
      0. ~ y_d - θ(t, ω) - κ(t, p_e, u)/u
]
ModelingToolkit.@named sfcinventory = ModelingToolkit.ODESystem(sfc)
korsbo commented 2 years ago

I'm guessing that you're hitting the problem described here https://github.com/korsbo/Latexify.jl/issues/194#issuecomment-980846915

There's no great way of dealing with snake-case function names vs underscores as subscript denotation when you're mixing Julia and LaTeX.

finmod commented 2 years ago

My guess is: the subscripts should be UTF coded as _symbol{} as in $ \mathbf{y}_{\boldsymbol{e}} $ whereas at present they are just $y_{e}$ .

korsbo commented 2 years ago

It does not seem to me like you're using any bold characters at all in the example.

finmod commented 2 years ago

Using a cut and paste of codes in unicode2latex.jl, I managed to render a Julia code that I can live with. The only bold characters that are working are \mathbf and not much else. Letter subscripts for variables are rarely working but what you see below is fine with me. The latexify output is patchy with respect to the Julia coding. Why is mathbf working for yd and ye and not for omega and lamba?

Then there is a new issue when I apply full_equations(), the end of equations \\ appear to be missing in some of the equations thus precluding printing.

ModelingToolkit.@parameters begin

      η=500
      C=0.33
      b=0.135
      α=0.025
      β=0.02
      δ=0.05
      r=0.03

      ϕ₀=0.0401
      ϕ₁=6.41e-05

      k₀=-0.0065
      k₁=-5.0
      k₂=20
      ηu=0.2
      u_b=0.9 

      m=1.2
      γ=0.4
      f_d=0.1

      η₁=0.8
      η₂=0.2
      η₃=0.7
      ηₑ=0.8 

      θ₁=0.9 
      θ₂=0.8 
      θ₃=-5.0 
      e₁=0.0
      𝐠e= α + β
end    

@variables begin
      t
      𝛚(t) = 0.9
      𝛌(t) = 0.90
      𝐝(t) = 0.5
      𝐲e(t) = 0.9
      𝐮(t) = 0.8
      𝐲d(t) = 0.9

      𝛎(t) = 3.0
      𝛟(t)
      𝛊(t)
      𝛋(t)
      𝛑e(t)
      𝛉(t) 
      𝐠(t)  
end

Dₜ = Differential(t)
tmax = 25.0                         # 25 years

# Behavioural equations

𝛑e = (t, 𝛚, 𝐲e, 𝐝) ->               𝐲e*(1 - 𝛚) - r*𝐝
𝛎  = (t, 𝛚) ->                      (1/C)*((1 -  𝛚)/b)^(-1/η)
𝛟  = (t, 𝛌) ->                      -ϕ₀ + ϕ₁/((1 - 𝛌)^2)
𝛊  = (t, 𝛚, 𝐲d, 𝐲e) ->              η₁*(m*𝛚 − 1) + η₂*(𝐲d - 𝐲e)
𝛋  = (t, 𝛑e, 𝐮) ->                  k₀ + exp(k₁+ k₂*𝛑e(t, 𝛚, 𝐲e, 𝐝)) + ηu*(𝐮 - u_b)
𝛉  = (t, 𝛚) ->                      θ₁/((1 + θ₂*exp(θ₃*𝛚))^(1/η₂))
𝐠  = (t, 𝐲d, 𝐲e) ->                 (f_d*(𝐠e + η₃) + 1.0)*(𝐲e*𝐠e +ηₑ*(𝐲d - 𝐲e)) + η₃*(𝐲d - 1)

sfc = [
      Dₜ(𝛚)  ~ 𝛚*(η/(1 + η))*(𝛟(t,𝛌) - α - (1 - γ)*𝛊(t, 𝛚, 𝐲d, 𝐲e))
      Dₜ(𝛌)  ~ 𝛌*(𝐠(t, 𝐲d, 𝐲e) - α - β)
      Dₜ(𝐝) ~ 𝐝*(r - 𝐠(t, 𝐲d, 𝐲e) - 𝛊(t, 𝛚, 𝐲d, 𝐲e)) + 𝛚 - 𝛉(t, 𝛚)
      Dₜ(𝐲e) ~ 𝐲e*(𝐠e - 𝐠(t, 𝐲d, 𝐲e)) + ηₑ*(𝐲d - 𝐲e)
      Dₜ(𝐮)  ~ 𝐮*(𝐠(t, 𝐲d, 𝐲e) - 𝛋(t, 𝛑e, 𝐮)/𝛎(t, 𝛚) + δ)
      0. ~ 𝐲d - 𝛉(t, 𝛚) - 𝛋(t, 𝛑e, 𝐮)/𝐮
]
ModelingToolkit.@named sfcinventory = ModelingToolkit.ODESystem(sfc)
reducedsfc = structural_simplify(sfcinventory)
full_equations(reducedsfc)
gustaphe commented 2 years ago

There's two different questions here:

In #208 I made the choice to maintain the difference between bold+italic and bold+upright, for instance. But that means your TeX compiler needs to have access to fonts like \mathbfit, so you need to \usepackage{unicode-math} (or other math font packages) in your document. If you're rendering this using mathjax (in Pluto notebooks, for instance) it's pretty unlikely they know what to do with these commands. But that's not a problem Latexify.jl can solve: Without these packages LaTeX simply can't render a bold \omega.

That said, if you find one of these symbols that you think the system should be able to typeset but isn't, especially if you know a LaTeX command that produces it correctly, please do show it with an MWE: code that runs by itself, including any using statements, and with as little as possible extra information. Preferably together with the output you would expect. Because it's really hard to tell what is wrong from just a snippet of code that doesn't even run.

finmod commented 2 years ago

This is fine and you can close this issue. The lesson is that an ample range of unicodes is made available by Latexify in unicode2latex.jl. This should be mentioned in the README. From then on, the user has to experiment on what he can obtain both in Julia code and in an editor to his needs knowing that there is no agreed UTF minimal standard across all software.

finmod commented 2 years ago

Let me suggest that Latexify should accommodate the JuliaMono font from here: https://cormullion.github.io/pages/2020-07-26-JuliaMono/ . The range of unicodes would be considerably increased as demonstrated in https://mono-math.netlify.app/.

korsbo commented 2 years ago

Latexify does not handle anything with fonts and it does not in any way draw the resulting equations. That's all for other packages and software to do. If you want to let your latex engine work with unicode rather than tex commands, then you have the convert_unicode = false kwarg. Latexify.jl's scope is to translate julia stuff to LaTeX code. Latexify then creates a LaTeXString from LaTeXStrings.jl and the rendering of that string is out of scope. If the LaTeX code coming from Latexify.jl is incorrect (which, indeed, it was when we first started addressing this issue) then that's an issue for here but now I no longer think that it is. The rest is up to whatever engine is being used to generate a picture from the LaTeX code - be it LaTeX, MathJax, Katex, or something else.