Rmarkdown inline latex error - knitr

I have an R function that returns text, including some LaTeX math mode, and I'm trying to use this text from an inline r chunk in an rmarkdown document. However, I get some quite strange behaviour regarding the use of math mode that I don't understand. It may be related to this question.
The following example works:
---
title: "Untitled"
output: pdf_document
---
```{r print_function}
print_fun <- function(x){
return(paste0("$\\mathrm{p}(\\beta < 0)$ > ", x))
}
x <- 0.5
```
Testing our printing function, we get `r print_fun(x)`.
Producing output
A small change breaks it
If I move the $ symbol a few places to the right, in order to also include the > sign within the math mode block, the document no longer compiles:
```{r print_function}
print_fun <- function(x){
return(paste0("$\\mathrm{p}(\\beta < 0) > $", x))
}
x <- 0.5
```
With the following error message:
Error producing PDF.
! LaTeX Error: \mathrm allowed only in math mode.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.137 ...g our printing function, we get \$\mathrm
Error: pandoc document conversion failed with error 43
Execution halted
This code works in an RSweave document, and I don't see why including the > symbol into math mode would have this effect.
Closing math mode after the numerical reference compiles again
```{r print_function}
print_fun <- function(x){
return(paste0("$\\mathrm{p}(\\beta < 0) > ", x, "$"))
}
x <- 0.5
```
Why?

This problem is to do with the space before the $ symbol in maths mode. From trial and error, this happens when the expression contains any maths function such as \\mathrm{}. So as minimal examples:
Works:
---
output: pdf_document
---
`r paste0("$\\mathrm{p}$")`
$\mathrm{p}$
Doesn't work:
---
title: "Untitled"
output: pdf_document
---
`r paste0("$\\mathrm{p} $")`
$\mathrm{p} $
Solution:
In your case, you are best off pasting the $ symbol after the value of the function:
print_fun <- function(x){
return(paste0("$\\mathrm{p}(\\beta < 0) >", x, "$"))
}
This lets you have the space after the > symbol.

Related

Why are Julia benchmarks not shown in VSCode?

Hi Below is some simple code that displays the benchmark results form a Julia REPL. In VSCode I have tried
launching the Julia REPL from the Command Pallet and Running the file without Debugging
Execute the active File in Repl from the drop down menu top right
In both cases the println statements are displayed but not the benchmark results. Is this to be expected or have I messed up?
using DifferentialEquations, BenchmarkTools
A = rand(1000,1000); B = rand(1000,1000); C = rand(1000,1000)
println("TX 1 and 2")
test(A,B,C) = A + B + C
#benchmark test(A,B,C)
println("T 1 End")
t(A,B,C) = A .+ B .+ C
#benchmark t(A,B,C)
println("TX 2 End")
readline()
println("After read")
I found a workaround : remove or comment out the #benchmark from the file and
run them directly in the REPL.
This should depend on which setting you have for result type (Julia > Execution: Result Type in the Settings GUI or julia.execution.resultType in settings.json).
With "inline" result type I get:
Hovering over the BenchmarkTools.Trial box, I get:
Note the println line just shows a tick as it has been executed but didn't return anything, instead it printed to the REPL, the terminal at the bottom now looks like this:

Strange output after putting a "prime" on an identifier in Racket REPL

Today, I made a typing mistake in the REPL and discovered a strange behaviour. Here's a sample of the interaction:
Welcome to Racket v6.11.
> (define x 3)
> x
3
> x'
3
> x
'x
>
So the first x I typed resulted in 3, which is expected. The x' I accidentally typed resulted in 3, which is unexpected. The last x resulted in 'x (!!).
It seems like there is something I don't understand about how the REPL reads values. Could someone explain why the REPL behaves in this way?
See Racketrivia: Using ' as an "identifier suffix" on the racket mailing list. The reply by Robby Findler and the reply by Matthias Felleisen both explain this.
The first line, x, is normal.
The second line, x', is actually an "expression and-a-half." It's interpreted as an expression x followed by an unfinished expression '. The unfinished expression is allowed to be finished on the next line. Whatever you put on the next line will be put as the second half of ' next-line.
That means the third x is actually interpreted as the second half of ' x.
You can see a better example of unfinished expressions with parentheses:
> 1 (list 2 ; 1 followed by an unfinished expression
1
> 3 4) ; finishing it
'(2 3 4)
> 3 4) ; on its own without the `(list 2` before it it's an error
3
4
; readline-input:13:3: read-syntax: unexpected `)` [,bt for context]
The quote after an expression is interpreted in a similar way:
> 1 ' ; 1 followed by an unfinished expression
1
> (indefatigable inexhaustible) ; finishes previously unfinished, put after a quote
'(indefatigable inexhaustible)
> (indefatigable inexhaustible) ; on its own without the quote before it it's an error
; indefatigable: undefined;
; cannot reference an identifier before its definition
; in module: top-level
; internal name: indefatigable

How do I get a newline in a Ipython output

Consider the following input in a IPython notebook:
mu = 39.95
Z=1
Latex(r"Atomic Mass: $\quad \mu$= %0.5e Hz" %(mu))
Latex(r"Charge state: $\quad z$= %0.5e" %(Z))
My question has two parts.
(A) Missing output
From above source, Surprisingly I got the following result:
Charge state: z = 1.00000e+00
What happened to the first line (i.e the value of $mu$ was not printed)?
(B) Missing newline
I was however able to get the result using the following:
Latex(r"Atomic Mass: $\quad \mu$= %0.5e Hz " %(mu) + r"Charge state: $\quad z$= %0.5e" %(Z))
But now, I need a newline in the above. How does one do it?
By default the notebook only renders the last value obtained in a cell. Use IPython.display.display as an augmented print function to display several things:
from IPython.display import Latex, display
mu = 39.95
Z=1
display(Latex(r"Atomic Mass: $\quad \mu$= %0.5e Hz" % mu))
display(Latex(r"Charge state: $\quad z$= %0.5e" % Z))

Quote-unquote idiom in Julia & concatenating Expr objects

I'd like to write a simple macro that shows the names & values of variables. In Common Lisp it would be
(defmacro dprint (&rest vars)
`(progn
,#(loop for v in vars
collect `(format t "~a: ~a~%" ',v ,v))))
In Julia I had two problems writing this:
How can I collect the generated Expr objects into a block? (In Lisp, this is done by splicing the list with ,# into progn.) The best I could come up with is to create an Expr(:block), and set its args to the list, but this is far from elegant.
I need to use both the name and the value of the variable. Interpolation inside strings and quoted expressions both use $, which complicates the issue, but even if I use string for concatenation, I can 't print the variable's name - at least :($v) does not do the same as ',v in CL...
My current macro looks like this:
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println(string(:($v), " = ", $v))) for v in vars]
ex
end
Looking at a macroexpansion shows the problem:
julia> macroexpand(:(#dprint x y))
quote
println(string(v," = ",x))
println(string(v," = ",y))
end
I would like to get
quote
println(string(:x," = ",x))
println(string(:y," = ",y))
end
Any hints?
EDIT: Combining the answers, the solution seems to be the following:
macro dprint(vars...)
quote
$([:(println(string($(Meta.quot(v)), " = ", $v))) for v in vars]...)
end
end
... i.e., using $(Meta.quot(v)) to the effect of ',v, and $(expr...) for ,#expr. Thank you again!
the #show macro already exists for this. It is helpful to be able to implement it yourself, so later you can do other likes like make one that will show the size of an Array..
For your particular variant:
Answer is Meta.quot,
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println($(Meta.quot(v)), " = ", $v)) for v in vars]
ex
end
See with:
julia> a=2; b=3;
julia> #dprint a
a = 2
julia> #dprint a b
a = 2
b = 3
oxinabox's answer is good, but I should mention the equivalent to ,#x is $(x...) (this is the other part of your question).
For instance, consider the macro
macro _begin(); esc(:begin); end
macro #_begin()(args...)
quote
$(args...)
end |> esc
end
and invocation
#begin x=1 y=2 x*y
which (though dubiously readable) produces the expected result 2. (The #_begin macro is not part of the example; it is required however because begin is a reserved word, so one needs a macro to access the symbol directly.)
Note
julia> macroexpand(:(#begin 1 2 3))
quote # REPL[1], line 5:
1
2
3
end
I consider this more readable, personally, than pushing to the .args array.

Interpolating an expression into an expression inside of a quote

This question builds off of a previous SO question which was for building expressions from expressions inside of of a macro. However, things got a little trucker when quoting the whole expression. For example, I want to build the expression :(name=val). The following:
macro quotetest(name,val)
quote
nm = Meta.quot($(QuoteNode(name)))
v = Meta.quot($(QuoteNode(val)))
println(nm); println(typeof(nm))
println(v); println(typeof(val))
end
end
#quotetest x 5 # Test case: build :(x=5)
prints out
:x
Expr
$(Expr(:quote, 5))
Expr
showing that I am on the right path: nm and val are the expressions that I want inside of the quote. However, I can't seem to apply the previous solution at this point. For example,
macro quotetest(name,val)
quote
nm = Meta.quot($(QuoteNode(name)))
v = Meta.quot($(QuoteNode(val)))
println(nm); println(typeof(nm))
println(v); println(typeof(v))
println(:($(Expr(:(=),$(QuoteNode(nm)),$(QuoteNode(val))))))
end
end
fails, saying nm is not defined. I tried just interpolating without the QuoteNode, escaping the interpolation $(esc(nm)), etc. I can't seem to find out how to make it build the expression.
I think you are using $ signs more than you need to. Is this what you're looking for?
julia> macro quotetest(name,val)
quote
expr = :($$(QuoteNode(name)) = $$(QuoteNode(val)))
println(expr)
display(expr)
println(typeof(expr))
end
end
#quotetest (macro with 1 method)
julia> #quotetest test 1
test = 1
:(test = 1)
Expr