How do you convert a string reprsentation of a polynomial back to a polynomial in a polynomial ring

544 views
Skip to first unread message

Stephen Kauffman

unread,
May 29, 2014, 2:13:19 PM5/29/14
to sage-s...@googlegroups.com
Specifically I have a polynomial such as mypoly = X*Y + 1 in BooleanPoynomialRing() and str(mypoly) converts it to the string 'X*Y + 1' then I do some stuff with re pattern matching to construct the string '1 - x*y' which I now want to convert to a polynomial in 'x' and 'y' in QQ. Are there any built in functions or methods to do that? Or does a python routine have to be written to accomplish my task? Thanks

William Stein

unread,
May 29, 2014, 2:17:46 PM5/29/14
to sage-support
R.<x,y> = PolynomialRing(QQ)
f = R('1 - x*y')
f

>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-support...@googlegroups.com.
> To post to this group, send email to sage-s...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.



--
William Stein
Professor of Mathematics
University of Washington
http://wstein.org

Stephen Kauffman

unread,
May 29, 2014, 2:21:04 PM5/29/14
to sage-s...@googlegroups.com
That's a lot simpler than I thought it would be. Thanks. I'm converting free boolean algebra statements to corresponding probability statements with a recursive function hopefully.

William Stein

unread,
May 29, 2014, 2:28:17 PM5/29/14
to sage-support
On Thu, May 29, 2014 at 11:22 AM, Stephen Kauffman
<strang...@gmail.com> wrote:
> That's a lot simpler than I thought it would be. Thanks. I'm converting free boolean algebra statements to corresponding probability statements with a recursive function hopefully.
>

Yep, there's a general Sage convert functionality, which is often
R(foo), where R is a parent object, and foo is anything that might
make sense. Be careful though, since it can easily lead to
mathematically meaningless results, since "R(foo)" in Sage means "make
something in R from foo by hook or crook".

Another useful command is sage_eval, which is like Python's eval, but
with the preparser:

R.<x,y> = PolynomialRing(QQ)
sage_eval('1 - x*y', globals())
-x*y + 1

Note that I expect this to work, but it doesn't:

R.<x,y> = PolynomialRing(QQ)
sage_eval('1 - x*y', {x:x, y:y})

Simon King

unread,
May 29, 2014, 2:37:39 PM5/29/14
to sage-s...@googlegroups.com
Hi Stephen

On 2014-05-29, Stephen Kauffman <strang...@gmail.com> wrote:
> Specifically I have a polynomial such as mypoly = X*Y + 1 in
> BooleanPoynomialRing() and str(mypoly) converts it to the string 'X*Y + 1'
> then I do some stuff with re pattern matching to construct the string '1 -
> x*y' which I now want to convert to a polynomial in 'x' and 'y' in QQ. Are
> there any built in functions or methods to do that?

Generally, if you have an algebraic structure Y (often called "parent") in
Sage, and have some element x of some other algebraic structure x, then
Y(x) tries to convert x into an element of Y. The same holds for
conversion of a string.

Note, however, that a conversion is not necessarily making mathematical
sense, if the structures X and Y are too different (i.e., there may be
no homomorphism from X to Y). So, use conversions only if you know what
you are doing.

What you describe would be as follows:
sage: P.<x,y> = BooleanPolynomialRing()
sage: mypoly = x*y+1
sage: R = QQ['x','y']
sage: R(mypoly)
x*y + 1
sage: R('1-x*y') # replacing + by - in str(mypoly)
x*y - 1

Best regards,
Simon


William Stein

unread,
May 29, 2014, 2:48:02 PM5/29/14
to sage-support
Simon -- great answer -- like my second one but even better. This
seems like the sort of thing our FAQ should have. Believe it or not,
we have a Sage FAQ:

http://sagemath.org/doc/faq/

I doubt it has been touched in years, and I doubt anybody even knows
how to change it...

Kannappan Sampath

unread,
May 29, 2014, 9:04:49 PM5/29/14
to sage-s...@googlegroups.com
And, this one still mentions Mercurial for the development among other things!!! I have opened a ticket to change this (now, I will have to figure how to do that but still...): 


-- Kannappan. 

leif

unread,
May 30, 2014, 10:26:26 AM5/30/14
to sage-s...@googlegroups.com
Kannappan Sampath wrote:
> On Fri, May 30, 2014 at 12:17 AM, William Stein <wst...@gmail.com
> <mailto:wst...@gmail.com>> wrote:
>
> Simon -- great answer -- like my second one but even better. This
> seems like the sort of thing our FAQ should have. Believe it or not,
> we have a Sage FAQ:
>
> http://sagemath.org/doc/faq/
>
> I doubt it has been touched in years, and I doubt anybody even knows
> how to change it...

$ git log src/doc/en/faq/ | grep '^Date:' | head -20
Date: Sat Feb 22 21:59:36 2014 +0100
Date: Tue May 21 00:54:32 2013 +0300
Date: Thu Apr 4 10:42:44 2013 -0700
Date: Tue Feb 14 00:12:31 2012 +0100
Date: Sat Jun 11 09:48:38 2011 +0200
Date: Thu Sep 27 11:08:34 2012 -0700
Date: Sun Aug 26 17:32:18 2012 +0200
Date: Fri Sep 21 16:03:42 2012 +0200
Date: Sun Oct 10 20:58:48 2010 +0200
Date: Mon Jun 28 09:43:00 2010 -0700
Date: Sun May 16 22:28:00 2010 -0700
Date: Sun Apr 4 16:47:15 2010 +0200
Date: Wed Mar 10 15:39:58 2010 -0800
Date: Mon Mar 8 14:09:13 2010 -0800

So at least a few developers are aware of it.


-leif

> And, this one still mentions Mercurial for the development among other
> things!!! I have opened a ticket to change this (now, I will have to
> figure how to do that but still...):
>
> http://trac.sagemath.org/ticket/16412
>
> -- Kannappan.

--
() The ASCII Ribbon Campaign
/\ Help Cure HTML E-Mail

Stephen Kauffman

unread,
May 30, 2014, 12:23:00 PM5/30/14
to sage-s...@googlegroups.com
I'm trying to become cognizant of your caveats about conversion. What I've tried to write is a recursive function to convert polynomials (statements) in the Free BooleanPolynomialRing() to corresponding probability polynomials (statements) over QQ. I haven't convinced myself that it's correct, but it checks out with some examples and also for basic forms however what I've just discovered is that as in below

EX7.<P,Q,R,S,V,W> = BooleanPolynomialRing(6,order='lex')
Prob(P + Q + R + S).ring() #yields an error message -- it doesn't seem to know that it's parent ring should be ProbRing

Traceback (most recent call last):
File "/projects/5511fe15-8085-4d1d-bdc7-c6bf6c99e693/.sagemathcloud/sage_server.py", line 733, in execute
exec compile(block+'\n', '', 'single') in namespace, locals
File "", line 1, in <module>
File "element.pyx", line 344, in sage.structure.element.Element.__getattr__ (sage/structure/element.c:4022)
File "misc.pyx", line 257, in sage.structure.misc.getattr_from_other_class (sage/structure/misc.c:1775)
AttributeError: 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular' object has no attribute 'ring'


#code
def ProbRecurse(myBP,BPR,ProbRing):
MyString = str(myBP)
if MyString == '1':
return 1
elif MyString == '0':
return 0
elif MyString.find(' 1') != -1:
return 1 - ProbRecurse(myBP + 1,BPR,ProbRing)
elif MyString.find('+') == -1:
return ProbRing(MyString.lower())
else:
kk = MyString.find(' + ')
myPoly1 = BPR(MyString[:kk])
myPoly2 = BPR(MyString[kk+3:])
return ProbRecurse(myPoly1,BPR,ProbRing) + ProbRecurse(myPoly2,BPR,ProbRing) - 2*ProbRecurse(myPoly1*myPoly2,BPR,ProbRing)

def Prob(myBP):
MyString = str(myBP)
if MyString == '1':
return 1
if MyString == '0':
return 0
BPR = myBP.ring() # seems to know it's parent ring
NewGens = str(BPR.gens()).lower()
NewGens=NewGens[1:len(NewGens) - 1]
ProbRing = PolynomialRing(QQ, len(myBP.args()) , NewGens.replace(', ',','), order=BPR.term_order()) # Create parent ProbRing -- inherit term-order and change gens case to lower
return ProbRecurse(myBP,BPR,ProbRing)

Prob(0)
Prob(1)
Prob(P*Q*R) # P and Q and R
Prob(P*Q + P + Q) # P or Q
Prob(P*Q + P + 1) # if P then Q
Prob(P + Q) # P xor Q
Prob(P + Q + R) # P xor Q xor R
Prob(P + Q + R + S) # etc
Prob(P*Q*R + P + Q*R) # premise 1 of exercise 7
Prob(Q*R*V*W + Q*R*V + 1) # premise 2 of exercise 7
Prob(P*S + P + S*W + S + 1) # premise 3 of exercise 7
Prob(W + 1) # not but also premise 4 of exercise 7

0
1
p*q*r # these look like polynomials base_ring() identifies as QQ
-p*q + p + q
p*q - p + 1
-2*p*q + p + q
4*p*q*r - 2*p*q - 2*p*r + p - 2*q*r + q + r # not convinced yet
-8*p*q*r*s + 4*p*q*r + 4*p*q*s - 2*p*q + 4*p*r*s - 2*p*r - 2*p*s + p + 4*q*r*s - 2*q*r - 2*q*s + q - 2*r*s + r + s # not convinced yet
-p*q*r + p + q*r
q*r*v*w - q*r*v + 1
p*s - p + s*w - s + 1
-w + 1

#Then do stuff like this in EX7 = P.ring()
Pr1 = (P + R + P*R)*(P + Q + P*Q) # premises of argument exercise 7
Pr2 = 1 + Q*R + Q*R*(1 + V + V*W)
Pr3 = 1 + P + P*S + (1 + P + P*S)*(S + S*W)
Pr4 = 1 + W
Concl = 1 + V + V*S
Idl = ideal(Pr1 + 1, Pr2 + 1, Pr3 + 1, Pr4 + 1, Concl + 0) # assume conclusion false for indirect proof
proof = Idl.groebner_basis()
proof

[1] # this mean 1 = 0 i.e. inconsistent therefore indirect proof

ideal(Pr1 + 1,Pr2 + 1, Pr3 + 1, Pr4 + 1).groebner_basis()

[P, Q + 1, R + 1, S, V, W] # a unique set of truth values [P,Q,R,S,V,W]=[0,1,1,0,0,0]

#and generalize to probabilities with
ProbRing = PolynomialRing(QQ, len(Prob(P).args()) , Prob(P).args(), order=BPR.term_order()) # have to create the parent outside function
PRI=(Prob(P*Q*R + P + Q*R) - 7/10, Prob(Q*R*V*W + Q*R*V + 1) - 1/2, Prob(P*S + P + S*W + S + 1) - 1/3, Prob(W + 1) - 1/2)*ProbRing
PRI.groebner_basis()

[p*q*r - p - q*r + 7/10, p*s - p - 1/2*s + 2/3, p*v - p - 7/10*v + 1, q*r*s - 2/3*q*r - 2/5*s + 1/15, q*r*v - 1, s*v - 5/2*s - 1/6*v + 5/3, w - 1/2]

# of course solving a system may result in values unacceptable as probabilities outside interval [0,1]

leif

unread,
May 30, 2014, 2:01:59 PM5/30/14
to sage-s...@googlegroups.com
Stephen Kauffman wrote:
> I'm trying to become cognizant of your caveats about conversion. What I've tried to write is a recursive function to convert polynomials (statements) in the Free BooleanPolynomialRing() to corresponding probability polynomials (statements) over QQ. I haven't convinced myself that it's correct, but it checks out with some examples and also for basic forms however what I've just discovered is that as in below
>
> EX7.<P,Q,R,S,V,W> = BooleanPolynomialRing(6,order='lex')
> Prob(P + Q + R + S).ring() #yields an error message -- it doesn't seem to know that it's parent ring should be ProbRing
>
> Traceback (most recent call last):
> File "/projects/5511fe15-8085-4d1d-bdc7-c6bf6c99e693/.sagemathcloud/sage_server.py", line 733, in execute
> exec compile(block+'\n', '', 'single') in namespace, locals
> File "", line 1, in <module>
> File "element.pyx", line 344, in sage.structure.element.Element.__getattr__ (sage/structure/element.c:4022)
> File "misc.pyx", line 257, in sage.structure.misc.getattr_from_other_class (sage/structure/misc.c:1775)
> AttributeError: 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular' object has no attribute 'ring'
> [BIG SNIP]

You can use foo.parent() or parent(foo) instead.


-leif

leif

unread,
May 30, 2014, 2:40:42 PM5/30/14
to sage-s...@googlegroups.com
P.S.:

sage: FOO.<P,Q,R,S,V,W> = BooleanPolynomialRing(6,order='lex')
sage: FOO.gens()
(P, Q, R, S, V, W)
sage: bar_gens_str = ','.join([ str(g).lower() for g in FOO.gens() ])
sage: BAR = PolynomialRing(QQ, bar_gens_str)
sage: BAR
Multivariate Polynomial Ring in p, q, r, s, v, w over Rational Field


sage: FOO('P + Q').parent() # of course works without quotes as well
Boolean PolynomialRing in P, Q, R, S, V, W

sage: BAR('p + q').parent()
Multivariate Polynomial Ring in p, q, r, s, v, w over Rational Field
Reply all
Reply to author
Forward
0 new messages