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, 15 May 2013 12:30:34 +0200Unit conversionhttps://ask.sagemath.org/question/9555/unit-conversion/I'm not certain if the behaviour is correct in this example, or I am possibly misunderstanding something. Sorry about the lengthy example, but I had difficulties simplifying it into a simpler one.
# Setup units
lbf = units.force.pound_force;
inch = units.length.inch;
sec = units.time.second;
psi = lbf / inch^2;
gal = 231.0*inch^3;
min = 60.0*sec;
gpm = gal/min;
hole = gpm/sqrt(psi);
# Define the given constraints
FLext = 20000.0*lbf;
vext = 15.0*inch/sec;
FLret = -10000.0*lbf;
vret = -15.0*inch/sec;
# Assumed values
Ps = 3000.0*psi;
pv = 1.0;
pc = 1.4;
# System of 3 equations, 3 unknowns
ABE = var('A_BE');
ARE = var('A_RE');
kv = var('k_v');
eq1 = vext^2 == (Ps*ABE - FLext) * kv^2 / ABE^3 / (1 + pv^2 * pc^(-3));
eq2 = vret^2 == (FLret + Ps*ARE) * kv^2 / ARE^3 / (1 + pv^2 * pc^3);
eq3 = pc == ABE / ARE;
sol = solve([eq1, eq2, eq3], [ABE, ARE, kv], solution_dict=True);
sol = sol[1];
show(sol[ABE])
show(sol[ARE])
show(sol[kv])
# Showing the units of various variables
show(sol[kv].convert())
show(hole.convert())
show( (sol[kv]/hole).convert() ) # this should be dimensionless
# Showing the potential bug with unit conversion
show(sol[kv].convert(hole)) # ValueError: Incompatible units
Running the code, the section labelled `# Showing the units of various variables`, you can see the various units of the relevant variables. The code for `show( (sol[kv]/hole).convert() )` should return a dimensionless value, however it still shows units in the result. Looking at the non-numeric portions of it, everything appears to cancel. Running `show(sol[kv].convert(hole))` results in `ValueError: Incompatible units`. I expected a conversion into gpm/sqrt(psi) (i.e. holes).
What concerns me is my calculator (TI-92+) has conversion difficulties with this unit as well, being unable to convert. Is this the expected/normal/ideal behaviour for sage? If so, for what reason(s)? If not, what should I do?
Thank you,
menturiWed, 21 Nov 2012 20:06:03 +0100https://ask.sagemath.org/question/9555/unit-conversion/Answer by burcin for <p>I'm not certain if the behaviour is correct in this example, or I am possibly misunderstanding something. Sorry about the lengthy example, but I had difficulties simplifying it into a simpler one.</p>
<pre><code># Setup units
lbf = units.force.pound_force;
inch = units.length.inch;
sec = units.time.second;
psi = lbf / inch^2;
gal = 231.0*inch^3;
min = 60.0*sec;
gpm = gal/min;
hole = gpm/sqrt(psi);
# Define the given constraints
FLext = 20000.0*lbf;
vext = 15.0*inch/sec;
FLret = -10000.0*lbf;
vret = -15.0*inch/sec;
# Assumed values
Ps = 3000.0*psi;
pv = 1.0;
pc = 1.4;
# System of 3 equations, 3 unknowns
ABE = var('A_BE');
ARE = var('A_RE');
kv = var('k_v');
eq1 = vext^2 == (Ps*ABE - FLext) * kv^2 / ABE^3 / (1 + pv^2 * pc^(-3));
eq2 = vret^2 == (FLret + Ps*ARE) * kv^2 / ARE^3 / (1 + pv^2 * pc^3);
eq3 = pc == ABE / ARE;
sol = solve([eq1, eq2, eq3], [ABE, ARE, kv], solution_dict=True);
sol = sol[1];
show(sol[ABE])
show(sol[ARE])
show(sol[kv])
# Showing the units of various variables
show(sol[kv].convert())
show(hole.convert())
show( (sol[kv]/hole).convert() ) # this should be dimensionless
# Showing the potential bug with unit conversion
show(sol[kv].convert(hole)) # ValueError: Incompatible units
</code></pre>
<p>Running the code, the section labelled <code># Showing the units of various variables</code>, you can see the various units of the relevant variables. The code for <code>show( (sol[kv]/hole).convert() )</code> should return a dimensionless value, however it still shows units in the result. Looking at the non-numeric portions of it, everything appears to cancel. Running <code>show(sol[kv].convert(hole))</code> results in <code>ValueError: Incompatible units</code>. I expected a conversion into gpm/sqrt(psi) (i.e. holes).</p>
<p>What concerns me is my calculator (TI-92+) has conversion difficulties with this unit as well, being unable to convert. Is this the expected/normal/ideal behaviour for sage? If so, for what reason(s)? If not, what should I do?</p>
<p>Thank you,</p>
<p>menturi</p>
https://ask.sagemath.org/question/9555/unit-conversion/?answer=14291#post-id-14291It seems that the units end up in `sqrt()` expressions. Even if you have something like `sqrt(second^2)`, Sage does not simplify this automatically. This is a bug caused by the fact that `second` is a symbolic variable and unless you explicitly state the domain for a variable it is assumed to be complex. For a complex variable `x`, we can't say that `sqrt(x^2) = x`. But if `x > 0`, we can:
sage: var('y', domain='positive')
y
sage: sqrt(y^2)
y
sage: sqrt(x^2)
sqrt(x^2)
There is also the fact that `sqrt()` only performs trivial simplifications automatically. This is not simplified for instance:
sage: sqrt(y^2/(x+1))
sqrt(y^2/(x + 1))
Because of another bug, even though we already declared `y > 0`, we need to state this to Maxima before we can simplify further:
sage: t = sqrt(y^2/(x+1))
sage: t.simplify_radical()
abs(y)/sqrt(x + 1)
sage: assume(y > 0)
sage: t.simplify_radical()
y/sqrt(x + 1)
You might be able to work around your problems by combining some of the tricks above. It would be great if someone files a ticket to declare units as positive.Thu, 22 Nov 2012 10:30:04 +0100https://ask.sagemath.org/question/9555/unit-conversion/?answer=14291#post-id-14291Answer by David Bailey for <p>I'm not certain if the behaviour is correct in this example, or I am possibly misunderstanding something. Sorry about the lengthy example, but I had difficulties simplifying it into a simpler one.</p>
<pre><code># Setup units
lbf = units.force.pound_force;
inch = units.length.inch;
sec = units.time.second;
psi = lbf / inch^2;
gal = 231.0*inch^3;
min = 60.0*sec;
gpm = gal/min;
hole = gpm/sqrt(psi);
# Define the given constraints
FLext = 20000.0*lbf;
vext = 15.0*inch/sec;
FLret = -10000.0*lbf;
vret = -15.0*inch/sec;
# Assumed values
Ps = 3000.0*psi;
pv = 1.0;
pc = 1.4;
# System of 3 equations, 3 unknowns
ABE = var('A_BE');
ARE = var('A_RE');
kv = var('k_v');
eq1 = vext^2 == (Ps*ABE - FLext) * kv^2 / ABE^3 / (1 + pv^2 * pc^(-3));
eq2 = vret^2 == (FLret + Ps*ARE) * kv^2 / ARE^3 / (1 + pv^2 * pc^3);
eq3 = pc == ABE / ARE;
sol = solve([eq1, eq2, eq3], [ABE, ARE, kv], solution_dict=True);
sol = sol[1];
show(sol[ABE])
show(sol[ARE])
show(sol[kv])
# Showing the units of various variables
show(sol[kv].convert())
show(hole.convert())
show( (sol[kv]/hole).convert() ) # this should be dimensionless
# Showing the potential bug with unit conversion
show(sol[kv].convert(hole)) # ValueError: Incompatible units
</code></pre>
<p>Running the code, the section labelled <code># Showing the units of various variables</code>, you can see the various units of the relevant variables. The code for <code>show( (sol[kv]/hole).convert() )</code> should return a dimensionless value, however it still shows units in the result. Looking at the non-numeric portions of it, everything appears to cancel. Running <code>show(sol[kv].convert(hole))</code> results in <code>ValueError: Incompatible units</code>. I expected a conversion into gpm/sqrt(psi) (i.e. holes).</p>
<p>What concerns me is my calculator (TI-92+) has conversion difficulties with this unit as well, being unable to convert. Is this the expected/normal/ideal behaviour for sage? If so, for what reason(s)? If not, what should I do?</p>
<p>Thank you,</p>
<p>menturi</p>
https://ask.sagemath.org/question/9555/unit-conversion/?answer=14930#post-id-14930For now, I find it more useful to define my own units instead of using the build-in Sage units. For example, I would rewrite this code as follows:
# Setup units
# Define base units (kilogram, meter, second) and secondary units (lbf, inch, sec)
kilogram = var('kilogram', domain='positive'); assume(kilogram,'real');
meter = var('meter', domain='positive'); assume(meter,'real');
second = var('second', domain='positive'); assume(second,'real');
lbf = 4.44822162*kilogram*meter/second^2
inch = 0.0254*meter
sec = 1*second;
psi = lbf / inch^2;
gal = 231.0*inch^3;
min = 60.0*sec;
gpm = gal/min;
hole = gpm/sqrt(psi);
# Define the given constraints
FLext = 20000.0*lbf;
vext = 15.0*inch/sec;
FLret = -10000.0*lbf;
vret = -15.0*inch/sec;
# Assumed values
Ps = 3000.0*psi;
pv = 1.0;
pc = 1.4;
# System of 3 equations, 3 unknowns
ABE = var('A_BE');
ARE = var('A_RE');
kv = var('k_v');
eq1 = vext^2 == (Ps*ABE - FLext) * kv^2 / ABE^3 / (1 + pv^2 * pc^(-3));
eq2 = vret^2 == (FLret + Ps*ARE) * kv^2 / ARE^3 / (1 + pv^2 * pc^3);
eq3 = pc == ABE / ARE;
soln = solve([eq1, eq2, eq3], [ABE, ARE, kv], solution_dict=True);
sol = soln[1];
show(sol[ABE])
show(sol[ARE])
show(sol[kv])
# Showing the units of various variables
# Use .full_simplify()._convert(RR) to provide simplified results
show(sol[kv].full_simplify()._convert(RR))
show(hole.full_simplify()._convert(RR))
show((sol[kv]/hole).full_simplify()._convert(RR) ) # this should be dimensionless
# This final result is now dimensionless, as desired.
I am still playing around, but the main idea is define one's own units (as shown at the beginning of the above example) using "domain" and "assume" to ensure they are positive real. Methods such as ".full_simplify()" and "._convert(RR)" can then be used to produce simple numerical results with all the units correctly cancelled out.Wed, 15 May 2013 12:30:34 +0200https://ask.sagemath.org/question/9555/unit-conversion/?answer=14930#post-id-14930