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.Wed, 21 Nov 2018 06:40:18 +0100Evaluate from string an equation that has integer divisionhttps://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/ I have the following Python list that contains strings of equations.
L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
You can see that all of the equations have integer division. Because this is obtained by some program, I can not edit the strings.
When I evaluate for `t=1.0` with the following code in SageMath (for example), it does not evaluate as an Euclidean division.
F = function('F')(t)
for k in L:
F(t) = eval(k)
Fc = fast_callable(F, vars=[t])
val2eval = 1.0
print(Fc(val2eval).n(13))
It gives
1.00000000000000
1.00000000000000
2.00000000000000
And should be give
1.86587997307599
1.00029510077345
2.86617507384944
Of course I can solve this by modifying MANUALLY the strings of the equations by indicating that the denominator is a real number and not an integer (I put a decimal point at the end of the integer in the denominator) as following.
L = ['651/349.*t + 5382747/9778631000.', 't + 57879/196133000.', '1000/349.*t + 57879/68450417.']
But this is not the idea, the strings of the equations are generated automatically and one can not modify by editing manually, because it will be implemented in a process where it should be create at least 2000 equations.
Is there some elegant solution for this? --Many thanks!Sun, 18 Nov 2018 18:21:18 +0100https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/Answer by nbruin for <p>I have the following Python list that contains strings of equations.</p>
<pre><code>L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
</code></pre>
<p>You can see that all of the equations have integer division. Because this is obtained by some program, I can not edit the strings.</p>
<p>When I evaluate for <code>t=1.0</code> with the following code in SageMath (for example), it does not evaluate as an Euclidean division.</p>
<pre><code>F = function('F')(t)
for k in L:
F(t) = eval(k)
Fc = fast_callable(F, vars=[t])
val2eval = 1.0
print(Fc(val2eval).n(13))
</code></pre>
<p>It gives</p>
<pre><code>1.00000000000000
1.00000000000000
2.00000000000000
</code></pre>
<p>And should be give</p>
<pre><code>1.86587997307599
1.00029510077345
2.86617507384944
</code></pre>
<p>Of course I can solve this by modifying MANUALLY the strings of the equations by indicating that the denominator is a real number and not an integer (I put a decimal point at the end of the integer in the denominator) as following.</p>
<pre><code>L = ['651/349.*t + 5382747/9778631000.', 't + 57879/196133000.', '1000/349.*t + 57879/68450417.']
</code></pre>
<p>But this is not the idea, the strings of the equations are generated automatically and one can not modify by editing manually, because it will be implemented in a process where it should be create at least 2000 equations.</p>
<p>Is there some elegant solution for this? --Many thanks!</p>
https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?answer=44360#post-id-44360If you want to parse strings in the way that the sage prompt does it, you could use
eval(preparse(k))
It's also a little wasteful to call
F(t)=eval(preparse(k))
(that's not valid python syntax. The preparser does quite a bit with that as well). In fact, if you know you want to parse the strings into symbolic expressions, you might want to call
F=symbolic_expression(k).function(t)
if you want F to be a function in t rather than just an expression.Wed, 21 Nov 2018 06:40:18 +0100https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?answer=44360#post-id-44360Answer by slelievre for <p>I have the following Python list that contains strings of equations.</p>
<pre><code>L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
</code></pre>
<p>You can see that all of the equations have integer division. Because this is obtained by some program, I can not edit the strings.</p>
<p>When I evaluate for <code>t=1.0</code> with the following code in SageMath (for example), it does not evaluate as an Euclidean division.</p>
<pre><code>F = function('F')(t)
for k in L:
F(t) = eval(k)
Fc = fast_callable(F, vars=[t])
val2eval = 1.0
print(Fc(val2eval).n(13))
</code></pre>
<p>It gives</p>
<pre><code>1.00000000000000
1.00000000000000
2.00000000000000
</code></pre>
<p>And should be give</p>
<pre><code>1.86587997307599
1.00029510077345
2.86617507384944
</code></pre>
<p>Of course I can solve this by modifying MANUALLY the strings of the equations by indicating that the denominator is a real number and not an integer (I put a decimal point at the end of the integer in the denominator) as following.</p>
<pre><code>L = ['651/349.*t + 5382747/9778631000.', 't + 57879/196133000.', '1000/349.*t + 57879/68450417.']
</code></pre>
<p>But this is not the idea, the strings of the equations are generated automatically and one can not modify by editing manually, because it will be implemented in a process where it should be create at least 2000 equations.</p>
<p>Is there some elegant solution for this? --Many thanks!</p>
https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?answer=44331#post-id-44331One solution is to use Python3-style division, where the quotient
of two integers is a floating-point number.
The simplest way is to import `division` from `__future__`:
Use `.n(digits=13)` to get 13 decimal digits; using `.n(13)` gives 13 bits
of precision, so only 3 decimal digits.
sage: from __future__ import division
sage: L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
sage: t = SR.var('t')
sage: F = function('F')(t)
sage: for k in L:
....: F(t) = eval(k)
....: Fc = fast_callable(F, vars=[t])
....: val2eval = 1.0
....: print(Fc(val2eval).n(digits=13))
....:
1.865879973076
1.000295100773
2.866175073849
Sun, 18 Nov 2018 19:48:18 +0100https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?answer=44331#post-id-44331Comment by loSuarezB for <p>One solution is to use Python3-style division, where the quotient
of two integers is a floating-point number.</p>
<p>The simplest way is to import <code>division</code> from <code>__future__</code>:</p>
<p>Use <code>.n(digits=13)</code> to get 13 decimal digits; using <code>.n(13)</code> gives 13 bits
of precision, so only 3 decimal digits.</p>
<pre><code>sage: from __future__ import division
sage: L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
sage: t = SR.var('t')
sage: F = function('F')(t)
sage: for k in L:
....: F(t) = eval(k)
....: Fc = fast_callable(F, vars=[t])
....: val2eval = 1.0
....: print(Fc(val2eval).n(digits=13))
....:
1.865879973076
1.000295100773
2.866175073849
</code></pre>
https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44351#post-id-44351I put the sentence `from __future__ import division` at the beginning of my file `'twophasevolumeweightunsat.sage'` and I become the following Error Message:
sage: load('twophasevolumeweightunsat.sage')
File "<string>", line 2
SyntaxError: from __future__ imports must occur at the beginning of the fileTue, 20 Nov 2018 17:45:13 +0100https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44351#post-id-44351Comment by loSuarezB for <p>One solution is to use Python3-style division, where the quotient
of two integers is a floating-point number.</p>
<p>The simplest way is to import <code>division</code> from <code>__future__</code>:</p>
<p>Use <code>.n(digits=13)</code> to get 13 decimal digits; using <code>.n(13)</code> gives 13 bits
of precision, so only 3 decimal digits.</p>
<pre><code>sage: from __future__ import division
sage: L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
sage: t = SR.var('t')
sage: F = function('F')(t)
sage: for k in L:
....: F(t) = eval(k)
....: Fc = fast_callable(F, vars=[t])
....: val2eval = 1.0
....: print(Fc(val2eval).n(digits=13))
....:
1.865879973076
1.000295100773
2.866175073849
</code></pre>
https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44352#post-id-44352I'm using `'SageMath version 7.5.1, Release Date: 2017-01-15'` because I could not install the new SageMath 8.X., this is another problem I would afford next.Tue, 20 Nov 2018 17:47:28 +0100https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44352#post-id-44352Comment by slelievre for <p>One solution is to use Python3-style division, where the quotient
of two integers is a floating-point number.</p>
<p>The simplest way is to import <code>division</code> from <code>__future__</code>:</p>
<p>Use <code>.n(digits=13)</code> to get 13 decimal digits; using <code>.n(13)</code> gives 13 bits
of precision, so only 3 decimal digits.</p>
<pre><code>sage: from __future__ import division
sage: L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
sage: t = SR.var('t')
sage: F = function('F')(t)
sage: for k in L:
....: F(t) = eval(k)
....: Fc = fast_callable(F, vars=[t])
....: val2eval = 1.0
....: print(Fc(val2eval).n(digits=13))
....:
1.865879973076
1.000295100773
2.866175073849
</code></pre>
https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44353#post-id-44353You could try putting the import statement at the start of the `init.sage` file
in the `.sage` folder in your home directory. Create the `init.sage` file if it
does not exist yet.Tue, 20 Nov 2018 18:22:39 +0100https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44353#post-id-44353Comment by slelievre for <p>One solution is to use Python3-style division, where the quotient
of two integers is a floating-point number.</p>
<p>The simplest way is to import <code>division</code> from <code>__future__</code>:</p>
<p>Use <code>.n(digits=13)</code> to get 13 decimal digits; using <code>.n(13)</code> gives 13 bits
of precision, so only 3 decimal digits.</p>
<pre><code>sage: from __future__ import division
sage: L = ['651/349*t + 5382747/9778631000', 't + 57879/196133000', '1000/349*t + 57879/68450417']
sage: t = SR.var('t')
sage: F = function('F')(t)
sage: for k in L:
....: F(t) = eval(k)
....: Fc = fast_callable(F, vars=[t])
....: val2eval = 1.0
....: print(Fc(val2eval).n(digits=13))
....:
1.865879973076
1.000295100773
2.866175073849
</code></pre>
https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44354#post-id-44354Or you could convert your file `twophasevolumeweightunsat.sage`
into `twophasevolumeweightunsat.py`; this might involve modifying
your code to turn it into pure Python syntax, and adding imports
for all the Sage functions that are used in this file.Tue, 20 Nov 2018 18:24:59 +0100https://ask.sagemath.org/question/44328/evaluate-from-string-an-equation-that-has-integer-division/?comment=44354#post-id-44354