On Mar 2, 2:34 pm, Alex Ghitza <[email protected]> wrote:
> The way I see it, it is not actually a question about the variable
> representing a real number; it is more a question of using polynomials
> and their specialised built-in roots() method rather than symbolic
> functions and the general-purpose solve().
>
>
> There might be an elegant way of doing this with symbolics, but I don't
> know it. However, if I move everything to one side of the == sign, your
> f is a rational function (quotient of polynomials with real
> coefficients). So my approach would be:
>
> sage: R.<y2> = RR[] # polynomials in y2 with real coefficients
> sage: f = y2 + 0.0906104881640050/y2^2 + 0.150000000000000 - 1.54027132807289
> sage: f.numerator().roots()
> [(-0.236040904804615, 1), (0.286518993973450, 1), (1.33979323890405, 1)]
>
> Note that the first line tells Sage what y2 is: the variable in a
> polynomial ring with real coefficients. Then when you define f, Sage
> automatically knows that f is a rational function (in particular, it's
> not an element of R, but of the fraction field of R:
> sage: parent(f)
> Fraction Field of Univariate Polynomial Ring in y2 over Real Field with 53
> bits of precision
> )
>
> Anyway, I think it would make perfect sense to be able to just do
> f.roots() for a rational function and have this return the roots of the
> numerator, so that would make this a bit nicer. For that matter, I
> think that for a rational function f we should have both f.zeroes() and
> f.poles() (and maybe also f.divisor()), and have f.roots() be an alias
> for f.zeroes().
>
> And again, maybe there should be a nice way of doing this within
> symbolics and somebody else can comment on this.
>
> Best,
> Alex
>
> --
> Alex Ghitza --http://aghitza.org/
> Lecturer in Mathematics -- The University of Melbourne -- Australia
Thanks again for taking the time to reply and please excuse my
apparent stubbornness-- I'm still trying to wrap my head around how/
why SAGE does some of the things it does so that I can build a
workflow around it.
My problem is that I can't figure out a way to start in the polynomial
ring because I'm starting with a system of physically based equations
and I would like to shown them with both a left and a right hand
side. For example, the problem I was considering concerned open
channel flow in the presence of an obstruction. The quantities of
interest are the water heights (y) and velocities (V) both upstream
and downstream of the obstruction which has a height of delta z. The
important relationships are conservation of energy and continuity:
y1, y2, V1, V2, delZ, g = var( 'y1 y2 V1 V2 delZ g' )
energyBal = V1^2 / (2*g) + y1 == V2^2 / (2*g) + y2 + delZ
continuityEq = V1 * y1 == V2 * y2
I know some given information:
knownInfo = {
V1: 8/9,
y1: 1.5,
delZ: 0.15,
g: 9.81
}
So, then I can apply some substitution and solving to come up with my
cubic:
altDepths = energyBal.subs( continuityEq.subs(knownInfo).solve(V2)
[0] ).subs(knownInfo)
print( altDepths )
1.54027132807289 == y2 + 0.0906104881640050/y2^2 + 0.150000000000000
The whole reason I've been sticking so stubbornly to symbolic
expressions is that Polynomial Rings won't let me write the equations
in "natural" form-- such as showing that the analysis starts from the
assumption that E1 = E2. So here I am looking for a nice way to
coerce what is obviously a polynomial to a Polynomial Ring. At first,
I thought the obvious answer would be to call:
altDepths.poly( y2 )
But that doesn't work. The poly() function appears to only deal with
re-arranging the coefficients of the polynomial if it is expressed in
more than one symbol. The behavior I would expect would be to also
examine the exponents of the polynomial terms in addition to the
coefficients-- something like the following:
def asPoly( express, sym ):
# Subtract everything to the left hand side
express = express - express.rhs()
# Recover coefficients for symbol
coeffList = express.coeffs( sym )
# Recover negative polynomial powers
powers = [ coef[1] for coef in coeffList if coef[1] < 0 ]
# If there are negative polynomial powers, multiply the
# expression by the absolute value of the smallest one.
if len( powers ):
express = express * sym ^ abs( min( powers ) )
return( express.full_simplify() )
Please excuse the code-- that was my very first python function and
I'm sure I abused most every language construct I used. It does what
I want, but there's still some weirdness that throws me off:
asPoly( altDepths, y2 )
-y2^3 + 1.39027132807*y2^2 - 0.090610488164 == 0
# Looks good
asPoly( altDepths, y2 ).is_polynomial()
False
# Fail.
asPoly( altDepths, y2 ).polynomial( RR ).roots()
[(-0.236040904804615, 1), (0.286518993973450, 1), (1.33979323890406,
1)]
# But it still gives me what I wanted
So I guess at this point my question is: is there another way to
convert from a symbolic polynomial equation to a Polynomial Ring? I
The methods I used feel very hacky and I don't trust them.
-Charlie
--
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sage-support
URL: http://www.sagemath.org