ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Sat, 20 May 2023 06:49:56 +0200How to substitute a value into an expression without evaluation to convert it to LaTex?https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/How can I convert an expression to LaTex while substituting a variable value
without evaluating the expression after substitution?
For example,
I have an expression `5*x*y`.
The `latex(5*x*y)` is `5 \, x y` as expected.
But now I want to substitute a constant instead of a variable.
For example `8` instead of `x`.
The LaTex representation (`latex((5*x*y).subs(x=8))`)
of which is would be `40 \, y`, so the expression is automatically evaluated.
But I want to get something like `5 \\cdot 8 y` instead.
Is that possible to do with SageMath?
I know something like that exists in SymPy. For example, take a look at the answer to:
- [Stack Overflow question 49842196: Substitute in sympy wihout evaluating or simplifying the expression](https://stackoverflow.com/questions/49842196)
It uses `sympy.UnevaluatedExpr` to wrap an expression to substitute the variable with.
Is there anything like that in SageMath?Thu, 18 May 2023 18:32:14 +0200https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/Comment by slelievre for <p>How can I convert an expression to LaTex while substituting a variable value
without evaluating the expression after substitution?</p>
<p>For example,
I have an expression <code>5*x*y</code>.
The <code>latex(5*x*y)</code> is <code>5 \, x y</code> as expected.
But now I want to substitute a constant instead of a variable.
For example <code>8</code> instead of <code>x</code>.
The LaTex representation (<code>latex((5*x*y).subs(x=8))</code>)
of which is would be <code>40 \, y</code>, so the expression is automatically evaluated.
But I want to get something like <code>5 \\cdot 8 y</code> instead.
Is that possible to do with SageMath?</p>
<p>I know something like that exists in SymPy. For example, take a look at the answer to:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/49842196">Stack Overflow question 49842196: Substitute in sympy wihout evaluating or simplifying the expression</a></li>
</ul>
<p>It uses <code>sympy.UnevaluatedExpr</code> to wrap an expression to substitute the variable with.
Is there anything like that in SageMath?</p>
https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?comment=68569#post-id-68569Welcome to Ask Sage! Thank you for your question!Fri, 19 May 2023 21:27:49 +0200https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?comment=68569#post-id-68569Answer by user98448 for <p>How can I convert an expression to LaTex while substituting a variable value
without evaluating the expression after substitution?</p>
<p>For example,
I have an expression <code>5*x*y</code>.
The <code>latex(5*x*y)</code> is <code>5 \, x y</code> as expected.
But now I want to substitute a constant instead of a variable.
For example <code>8</code> instead of <code>x</code>.
The LaTex representation (<code>latex((5*x*y).subs(x=8))</code>)
of which is would be <code>40 \, y</code>, so the expression is automatically evaluated.
But I want to get something like <code>5 \\cdot 8 y</code> instead.
Is that possible to do with SageMath?</p>
<p>I know something like that exists in SymPy. For example, take a look at the answer to:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/49842196">Stack Overflow question 49842196: Substitute in sympy wihout evaluating or simplifying the expression</a></li>
</ul>
<p>It uses <code>sympy.UnevaluatedExpr</code> to wrap an expression to substitute the variable with.
Is there anything like that in SageMath?</p>
https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?answer=68584#post-id-68584I found another solution, which is better for me.
It still requires me to use sympy, which is unfortunate because sympy symbols are incompatible with sage function declarations (`TypeError: must construct a function with symbolic variables as arguments`), but it's better than nothing.
There is a global thread-local parameters object `sympy.core.parameters.global_parameters` with a `evaluate` parameter that controls whether expressions should be evaluated or not.
We can explicitly change the value of `evaluate` parameter:
sympy.core.parameters.global_parameters.evaluate = False
Or do the same, but using context manager class `sympy.evaluate` that pushes the `evaluate` parameter value for us:
with sympy.evaluate(False):
print(x + x)
The `evaluate` global parameter is restored to the previous value once the code leaves the `with` statement.
This method is better than using `UnevaluatedExpr` because it doesn't mess with the order of expressions.
For instance:
sympy.latex((5*x*y).subs(x, sympy.UnevaluatedExpr(8)))
'5 y 8'
The order of `x` (substituted with 8) and `y` has been changed.
with sympy.evaluate(False):
print(sympy.latex((5*x*y).subs(x, 8)))
5 \cdot 8 y
The order has not been changed.
I could not find such global parameter in sage. `hold` argument is False by default (from sage source code):
if kwds.get('hold', False):
While in sympy the default value of hold's alternative `evaluate` argument is the global parameter `evaluate`:
eval = options.pop('evaluate', global_parameters.evaluate)
I wish I was wrong and there was actually any way to globally disable expressions evaluation in sagemath. I'm still looking for it :)Sat, 20 May 2023 06:49:56 +0200https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?answer=68584#post-id-68584Answer by dazedANDconfused for <p>How can I convert an expression to LaTex while substituting a variable value
without evaluating the expression after substitution?</p>
<p>For example,
I have an expression <code>5*x*y</code>.
The <code>latex(5*x*y)</code> is <code>5 \, x y</code> as expected.
But now I want to substitute a constant instead of a variable.
For example <code>8</code> instead of <code>x</code>.
The LaTex representation (<code>latex((5*x*y).subs(x=8))</code>)
of which is would be <code>40 \, y</code>, so the expression is automatically evaluated.
But I want to get something like <code>5 \\cdot 8 y</code> instead.
Is that possible to do with SageMath?</p>
<p>I know something like that exists in SymPy. For example, take a look at the answer to:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/49842196">Stack Overflow question 49842196: Substitute in sympy wihout evaluating or simplifying the expression</a></li>
</ul>
<p>It uses <code>sympy.UnevaluatedExpr</code> to wrap an expression to substitute the variable with.
Is there anything like that in SageMath?</p>
https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?answer=68573#post-id-68573There are several ways to do it and you'll have to decide on which suits you best.
First method: Direct use of sympy. This didn't work out the way I expected: it switched x and y after substitution:
![image description](/upfiles/16845254384596898.jpg)
If that's okay then maybe this is good enough. I wouldn't want it swapping terms, so with a bit of fiddling came up with this, which is getting more involved:
import sympy
from sympy import *
x,y=symbols("x y")
expr = 5*x*y
from sympy import UnevaluatedExpr
print(latex(UnevaluatedExpr(sympify("5*8*y",evaluate=False))))
Now the order is correct but `latex(UnevaluatedExpr(sympify("5*8*y",evaluate=False)))` is a bit annoying
![image description](/upfiles/1684525760964652.jpg)
Note removing print from the last statement gives you your double escape: `'5 \\cdot 8 y'`
Second method is to work in strings. This will give you complete control over your output:
y=var("y")
expr = 5*x*y
expr = latex(expr).replace(r" \, ","")
s1 = expr.replace("x", r" \\cdot 8 ")
s2 = s1.replace("y",r"\\cdot 4 ")
print(s1,", ",s2)
The output is:
![image description](/upfiles/16845262158444288.jpg)
s1 is the output after the first step of substituting `x` for r" \\cdot 8 " while s2 would be a potential second step of substituting
`y` for r"\\cdot 4 ".
Third method, which might be useful depending on the context of how you are using the output, is to work directly in LaTeX and borrow from Sage as needed. This is typically how I work with both. Here is a sample LaTeX document:
\documentclass{article}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
var("y")
f(x,y)=5*x*y
g(y)=f(8,y)
\end{sagesilent}
Start with the expression $5xy$. Substitute $8$ for $x$ to get
$5 \cdot 8y = \sage{g(y)}$. Now substitute $y=4$ into
$\sage{g(y)}$ to get $40\cdot 4 = \sage{g(4)}$.
\end{document}
![image description](/upfiles/16845265203220996.jpg)
Fri, 19 May 2023 22:17:53 +0200https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?answer=68573#post-id-68573Answer by slelievre for <p>How can I convert an expression to LaTex while substituting a variable value
without evaluating the expression after substitution?</p>
<p>For example,
I have an expression <code>5*x*y</code>.
The <code>latex(5*x*y)</code> is <code>5 \, x y</code> as expected.
But now I want to substitute a constant instead of a variable.
For example <code>8</code> instead of <code>x</code>.
The LaTex representation (<code>latex((5*x*y).subs(x=8))</code>)
of which is would be <code>40 \, y</code>, so the expression is automatically evaluated.
But I want to get something like <code>5 \\cdot 8 y</code> instead.
Is that possible to do with SageMath?</p>
<p>I know something like that exists in SymPy. For example, take a look at the answer to:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/49842196">Stack Overflow question 49842196: Substitute in sympy wihout evaluating or simplifying the expression</a></li>
</ul>
<p>It uses <code>sympy.UnevaluatedExpr</code> to wrap an expression to substitute the variable with.
Is there anything like that in SageMath?</p>
https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?answer=68563#post-id-68563Sage has a "hold" context for some operations, but I don't see how to use it to answer the question.
Especially since the hold context seems quite fragile with respect to substitution.
As a workaround, one can use SymPy inside Sage.
Here are some things one can do with "hold", in case it helps.
sage: a = x
sage: a = a.mul(8, hold=True)
sage: a = a.mul(5, hold=True)
sage: a
5*(8*x)
sage: a.unhold()
40*x
Fri, 19 May 2023 18:40:00 +0200https://ask.sagemath.org/question/68529/how-to-substitute-a-value-into-an-expression-without-evaluation-to-convert-it-to-latex/?answer=68563#post-id-68563