How to create polynomials from strings - sage

I would like to create Boolean polynomials from strings. At the moment I define polynomials by using implicitly defined variables:
R = BooleanPolynomialRing(names=["a", "b", "c"], order=TermOrder("lex"))
R.inject_variables()
f = 1 + a*b
g = a*b*(1+c)
I would like to define f and g in terms of strings "1 + a*b" and "a*b*(1+c)".

The polynomial ring can take strings and transform them into polynomials.
sage: R = BooleanPolynomialRing(names=["a", "b", "c"], order=TermOrder("lex"))
sage: R.inject_variables()
Defining a, b, c
sage: f = R("1 + a*b")
sage: f
a*b + 1
sage: g = R("a*b*(1+c)")
sage: g
a*b*c + a*b

Related

How do I use method lagrange_polynomial over a PolynomialRing of Integers?

R.<x> = PolynomialRing(RR)
points = [(1,2), (2,2), (3,6)]
R.lagrange_polynomial(points)
2.00000000000000*x^2 - 6.00000000000000*x + 6.00000000000000
The above works fine but since all the coefficients are integers, I would prefer to do this over integers.
However when I try with
R.<x> = PolynomialRing(ZZ)
R.lagrange_polynomial(points)
I get the error
AttributeError: 'PolynomialRing_integral_domain_with_category' object has no attribute 'lagrange_polynomial'
I know I can use QQ instead of RR & get the coefficients printed as integers, but I am wondering why ZZ is not allowed?
The Lagrange polynomial for three points in ZZ^2 does not
always have coefficients in ZZ, so it makes sense to have
it as a method of QQ['x'] and not of ZZ['x'].
sage: R.<x> = PolynomialRing(QQ)
sage: points = [(0, 1), (1, 0), (2, 2)]
sage: R.lagrange_polynomial(points)
3/2*x^2 - 5/2*x + 1
Since for points = [(1, 2), (2, 2), (3, 6)] the Lagrange
polynomial's coefficients end up being integers, one can do:
sage: R.<x> = PolynomialRing(ZZ)
sage: points = [(1, 2), (2, 2), (3, 6)]
sage: q = R.change_ring(QQ).lagrange_polynomial(points)
sage: q
2*x^2 - 6*x + 6
sage: parent(q)
Univariate Polynomial Ring in x over Rational Field
sage: p = R(q)
sage: p
2*x^2 - 6*x + 6
sage: parent(p)
Univariate Polynomial Ring in x over Integer Ring

Symbolic Taylor expansion

I would like to expand the symbol function $f(x)$ as a Taylor series in SageMath
$$\delta f(x)=\delta x\frac{d}{dx}f+\frac12(\delta x)^2\frac{d^2}
{dx^2}f+O((\delta x)^3)$$
with
$$\delta x = a_1(\delta t)^{\frac12}+a_2(\delta t)+a_3(\delta t)^{\frac32}+O((\delta t)^2)$$
And expand and collect the same power terms of $\delta t$ up to a designated power, say, $\frac32$. $f$ is just a symbol, I just need Mathsage to produce the symbols of derivatives $\frac{d}{dx}$.
How should one set this up in SageMath?
Is this what you want to do?
sage: f = function('f', nargs=1)(x)
sage: f
f(x)
sage: f.taylor(x, 0, 2)
1/2*x^2*D[0, 0](f)(0) + x*D[0](f)(0) + f(0)
With sympy, you would do something like this to get the Taylor series.
import sympy
dt = sympy.Symbol('dt')
a1 = sympy.Symbol('a1')
a2 = sympy.Symbol('a2')
a3 = sympy.Symbol('a3')
dx = a1*dt**(1/2) + a2*dt + a3*dt**(3/2)
from sympy.abc import x
f = sympy.Function('f')(x)
df = dx*sympy.diff(f,x) + 1/2*dx**2*sympy.diff(f,x,2)
df.series(x)
This is assuming x and δx are independent.

Sage for Galois Field

I have a problem in Galois Field in SageMath. I can't convert a binary to polynomial.
If I have a binary number, 1010101 how do I convert this number in polynomial 1010101 = x^6+x^4+x^2+1.
I do not know if there is an inbuilt way (I presume you have already looked also), but you can always do the following:
sage: P.<x> = PolynomialRing(ZZ)
sage: binString = "1010101"
sage: arrayOfTerms = [0]*len(binString)
sage: binString = binString[::-1] #Flip it so that the first digit corresponds to the constant term
sage: for i in xrange(len(binString)):
....: arrayOfTerms[i] = (x**i)*int(binString[i])
....:
sage: poly = sum(arrayOfTerms)
sage: poly
x^6 + x^4 + x^2 + 1

How to express variable through other in SAGE

Is there way to express mathematical expression through variable defined earlier in SAGE?
For example if I have variable a = b + c, I want SAGE rewrite expression b + c + d as a + d.
Thank you.
In fact, substituting such expressions is a nontrivial thing if you don't know what part of the expression tree you want. See Richard Fateman's comments here.
The core of the problem is that even the command that would do what you want is not about strings, but expressions.
sage: var("a b c d")
(a, b, c, d)
sage: (a+d).subs({a:b+c})
b + c + d
sage: (b+c+d).subs({b+c:a})
b + c + d
So you will have to use a "wildcard".
sage: w0 = SR.wild(0)
sage: (b+c+d).subs({b+c+w0:a+w0})
a + d
For more information, see
sage: x.match?
sage: SR.wild?
in the interactive shell or notebook.
As you can see in calculus, you can express d as variable with
a = var('a'); b+c
or like a function of b and c variable

Sage: Finding linear combination of a specified basis giving a specified element?

Given a vector space V, a basis B (list of tuples each of size corresponding to the dimension of V and over the same field) and a vector v - what is the sage command to find the (unique) linear combination of the elements of B giving v?
IIUC, you probably want to do something like this:
sage: basis = [(2,3,4),(1,23/4,3), (9,8/17,11)]
sage: F = QQ
sage: F
Rational Field
sage:
sage: # build the vector space
sage: dim = len(basis[0])
sage: VS = (F**dim).span_of_basis(basis)
sage: VS
Vector space of degree 3 and dimension 3 over Rational Field
User basis matrix:
[ 2 3 4]
[ 1 23/4 3]
[ 9 8/17 11]
and then, having constructed the vector space over the field:
sage: # choose some random vector
sage: v = vector(F, (19/2, 5/13, -4))
sage: v
(19/2, 5/13, -4)
sage:
sage: # get its coordinates
sage: c = VS.coordinate_vector(v)
sage: c
(-470721/19708, 59705/4927, 24718/4927)
sage: parent(c)
Vector space of dimension 3 over Rational Field
sage:
sage: # aside: there's also .coordinates(), but that returns a list instead
sage:
sage: # sanity check:
sage: VS.basis_matrix().transpose() * c
(19/2, 5/13, -4)
sage: VS.basis_matrix().transpose() * c == v
True

Resources