# conversions from/to FunctionField(SR) and symbolic expression

Hello, read the following session OR if you won't please go directly to the question below

  \$ sage
----------------------------------------------------------------------
| Sage Version 5.6, Release Date: 2013-01-21                         |
----------------------------------------------------------------------
sage: a,b,s = var('a b s')
sage: expr1 = (a^2*s + 2)/(s^3 + s + 3) + s
sage: expr1.denominator()
s^3 + s + 3
sage: type(s)
<type 'sage.symbolic.expression.Expression'>
sage: FF.<s> = FunctionField(SR)
sage: FF(expr1)
s + (a^2*s + 2)/(s^3 + s + 3)
sage: FF(expr1).denominator()
1
# s in expr1 is NOT recognized as the s in the definition of the
# function field.
sage: type(s)
<type  'sage.rings.function_field.function_field_element.FunctionFieldElement_rational'>
# BUT:
sage: x = var('x')
sage: expr2 = x + (45^2 + 2)/(x^3 + x + 3)
sage: FF2.<x> = FunctionField(RR)
# now RR instead of SR and x as the variable.
sage: FF2(expr2)
(x^4 + x^2 + 3.00000000000000*x + 2027.00000000000)/(x^3 + x + 3.00000000000000)
sage: FF2(expr2).denominator()
x^3 + x + 3.00000000000000
# x is correctly recognized in expr2 but not in expr1 !
sage: type(x)
<type 'sage.rings.function_field.function_field_element.FunctionFieldElement_rational'>


QUESTION: a FunctionField over RR with the variable x correctly recognizes expressions where x=var('x') appears in the expression (see above), and the computation of denominator is correct; FunctionField over SR with the variable s do not recognizes expressions with s=var('s'); instead in this case the s is treated like a coefficient (denominator=1 in example above in the first part). How can i adjust this behavior, so that I obtain the same answer in both following cases:

     sage: expr1
s + (a^2*s + 2)/(s^3 + s + 3)
# here s = var('s') is symbolic expression
sage: FF(expr1).denominator()
1
# I DO NOT WANT THIS ANSWER
sage: FF(s + (a^2*s+2)/(s^3 + s + 3)).denominator()
s^3 + s + 3
# but this answer (that works if the expression is constructed by hand) with
sage: type(s)
<type 'sage.rings.function_field.function_field_element.FunctionFieldElement_rational'>


Any suggestion ? THANK YOU VERY MUCH !

edit retag close merge delete

Sort by » oldest newest most voted

I somehow prefer my previous answer, since it means that you were able to avoid Symbolic Ring annoyances from the beginning. Here is a workaround in case you are not able to build a rational function from the beginning.

So, you are given a symbolic expression as follows:

sage: a,b,s = var('a b s')
sage: expr1 = (a^2*s + 2)/(s^3 + s + 3) + s


We will recursively replace the symbolic variable s by the element FF(S) of the function field FF by hand as follows:

sage: FF.<S> = FunctionField(SR)

sage: def unfold_refold(expr):
sage:     operator = expr.operator()
sage:     if operator:
sage:         operands = expr.operands()
sage:         return reduce(operator, [unfold_refold(i) for i in operands])
sage:     elif expr == var('s'):
sage:         return FF(S)
sage:     else:
sage:         return expr

sage: expr2 = unfold_refold(expr1) ; expr2
(S^4 + S^2 + (a^2 + 3)*S + 2)/(S^3 + S + 3)
sage: expr2.parent()
Rational function field in S over Symbolic Ring
sage: expr2.numerator()
S^4 + S^2 + (a^2 + 3)*S + 2
sage: expr2.denominator()
S^3 + S + 3

more

P.S. my project is on:

https://github.com/alessandro-bernardini/SAPICE


and it is a full work in progress. The documentation has to be adjusted and rewritten because at the moment the documentation does not (more) match "the reality" in the software class SmallSignalLinearCircuit.

The class reads a ngspice netlist (for the moment only BJT are supported as active elements) computes the small signal linear(ized) circuit and the corresponding nodal equations that can be solved symbolically or numerically (with sage).

Impedances can be computed symbolically or numerically (and the two port network parameters) ... and poles/zeros as far as the polynomial degree allows a symbolic solution ( <= 4 ).

"Automatic" simplification is thus a key concept, and only those terms have to be considered that "dominates" and the others ignored.

For this functions like symplify_rational_func will play an important role.

more

If you're only interested in "dominant" terms it seems you should be working in some Laurent series ring. Computing with power series using only a limited number of terms gives significant performance improvements, at the cost of having to manage the number of terms you work with, of course. I don't know if the right kind of Laurent series (do you require them multivariate or would it be OK to have a laurent series over a function field?) is available already. If the arithmetic of SR isn't fast enough for you, you could also consider moving away from SR entirely: sage: R=PolynomialRing(QQ,names=tuple(str(u) for u in expr1.variables())) sage: FF=R.fraction_field() sage: FF(expr1) (s^4 + a^2*s + s^2 + 3*s + 2)/(s^3 + s + 3) sage: SR(FF(expr1)) (s^4 + a^2*s + s^2 + 3*s ...(more)

( 2013-10-22 08:55:23 -0500 )edit

and in case how can i do the inverse conversion... ?

more

Thank you:

the unfold_refold method in the post of tmonteil is maybe the best solution.

In the approach of nbruin I have following problem: - expr1 is a very very big rational function in s with symbolic coefficients resulting from a solution to a system of linear equations: in the specific from the system of nodal equations of a linear electric circuit in the Laplace domain... The system is solved not for s but for the nodal voltages and s=var('s') will be the complex angular frequency (a parameter).

Because the resulting expressions are very big I am automatically simplifying terms that evaluate to tiny (absolute) values - provided an initial (or typical) value for the circuit paramters.

For rational functions I need the numerator_denominator expressions, but it takes too long to compute them. With FunctionField it goes faster, but I have the conversion problem (in both directions).

I think s must remain symbolic because it is needed in the solution of the system of nodal equations. Or am I wrong here ?

In the answer of nbruin I have to compute numerator and denominator, which IS my problem because of runtime.

So the unfold_refold method can be a good idea: I will try it and let you know...

more

The problem is that if you ask sage to convert an expression from SR to FunctionField(SR,'<some var="" name="">') it can do so by considering the entire expression as a "constant" function as far as the function field is concerned. You'll have to tell sage that you want something different. One thing that doesn't work would be to evaluate the expression in the variable that you want:

expr1(s=FF.0)


This doesn't work because in sage, "symbolic expression evaluation" is expected to yield a "symbolic expression". Hence sage first tries to turn FF.0 into an SR element, and fails there (rightly): Note that in FF, we can only represent expressions that have FF.0 occur rationally, whereas in expr1 a priori, we might have variables also occur in exponents etc. So it wouldn't be safe for sage to try anything else.

If you absolutely have to do this, you'll have to do it by hand: determine the coefficients of the numerator and denominator as polynomials in s and reconstruct an element of FF out of it. That isn't as bad as it sounds:

def SRpoleval(expr,var,value):
return sum(c*value**e for c,e in expr.coefficients(var))
def SRtoFF(expr):
return SRpoleval(expr.numerator(),SR('s'),FF.0)/SRpoleval(expr.denominator(),SR('s'),FF.0)


With this you'll get

sage: SRtoFF(expr1)
(s^4 + s^2 + (a^2 + 3)*s + 2)/(s^3 + s + 3)
sage: SRtoFF(expr1).denominator()
s^3 + s + 3


Now do

sage: SRtoFF((sin(SR('s'))+SR('s')^2)/(exp(1+SR('s')^2)-SR('s')^2))
(-s^2 - sin(s))/(s^2 - e^(s^2 + 1))


to see why you should probably not do this in general. I doubt that creating a function field over SR is the best solution to whatever problem you are working on.

more

In your workflow, can you use the right s (as an element of FF, not SR) from the beginning ?

sage: a,b = var('a b')
sage: FF.<s> = FunctionField(SR)
sage: expr1 = (a^2*s + 2)/(s^3 + s + 3) + s
sage: expr1
(s^4 + s^2 + (a^2 + 3)*s + 2)/(s^3 + s + 3)
sage: expr1.numerator()
s^4 + s^2 + (a^2 + 3)*s + 2
sage: expr1.denominator()
s^3 + s + 3


Or is the fact that s as a symbolic variable in expr1 can not be changed in the beginning absolute ?

more