These are chat archives for symengine/symengine

21st
Jun 2016
Isuru Fernando
@isuruf
Jun 21 2016 03:26
You are right, it should not use x+y as a generator
In [3]: Poly((x+y)**2+1)
Out[3]: Poly(x**2 + 2*x*y + y**2 + 1, x, y, domain='ZZ')
Ralf Stephan
@rwst
Jun 21 2016 06:19
However,
In [1]: Poly((x+sin(y))**2+1)
Out[1]: Poly(x**2 + 2*x*(sin(y)) + (sin(y))**2 + 1, x, sin(y), domain='ZZ')
i.e. no y
Srajan Garg
@srajangarg
Jun 21 2016 06:21
Yes
@isuruf what should I use as a default generator if no generator is provided by the user? can I use the raw NULL pointer?
I mean, RCP<const UIntPoly> basic_to_uintpoly(const RCP<const Basic> &x, RCP<const Basic> gen = NULL)
and then for eg, in the visitor I have,
void bvisit(const Integer &x)
{   
    if (gen != NULL)
        res = UIntPoly::from_container(gen, std::move({{0, x.i}}));
    else
        throw runtime error;
}
Isuru Fernando
@isuruf
Jun 21 2016 06:27
You can have two methods. One taking a gen argument and another without. Function not taking the generator in can calculate the generators and use them
Srajan Garg
@srajangarg
Jun 21 2016 06:27
Updated above code
They will have separate visitors then?
That will be very redundant I feel, but actually
I would anyways have to check everytime if gen is null or not
so i guess ill make two visitors
Isuru Fernando
@isuruf
Jun 21 2016 06:30
One visitor to figure out the generators.
Another visitor to convert the polynomial
Srajan Garg
@srajangarg
Jun 21 2016 06:30
I see
On a side note, why are we moving away from flint c++ api to our own wrappers?
Isuru Fernando
@isuruf
Jun 21 2016 06:36
It doesn't work with MSVC
Srajan Garg
@srajangarg
Jun 21 2016 07:57
Do you have any other genarators in mind apart from these (for the univariate case), Symbol eg. x + 1, Pow eg. 2**x + 1, Function eg. sin(x) + 1
Add and Mul type Basics can't ever be generators, am I right?
Isuru Fernando
@isuruf
Jun 21 2016 08:37
You can take a look at SymPy source code
Kalevi Suominen
@jksuom
Jun 21 2016 09:13
I think the useful generators would be symbols and functions (including non-integer powers). SymPy seems to allow also more general expressions, but I suspect that they would not be of much practical use.
Srajan Garg
@srajangarg
Jun 21 2016 11:25
In [30]: tbt = Rational(3, 2)
In [31]: Poly(x**tbt + x + 1)
Out[31]: Poly(x + sqrt(x)**3 + 1, x, sqrt(x), domain='ZZ')
I expected
Out[31]: Poly(sqrt(x)**3 + x + 1, sqrt(x), domain='ZZ')
Isuru Fernando
@isuruf
Jun 21 2016 11:26
That's a too extreme case IMO
Srajan Garg
@srajangarg
Jun 21 2016 11:26
Okay, I'll try to handle it though
Also, printing x**(1/2) instead of sqrt(x) is alright?
Isuru Fernando
@isuruf
Jun 21 2016 11:29
yes
We should change that in the string printer though
Srajan Garg
@srajangarg
Jun 21 2016 11:35
I had to change the printing a little bit, to incorporate Pow var_s
Are these okay?
RCP<const Symbol> x = symbol("x");
RCP<const Basic> p = pow(integer(2), x);
RCP<const Basic> t = pow(x, rational(3,2));
RCP<const Basic> s = sqrt(x);
RCP<const Basic> sinx = sin(x);

RCP<const UIntPoly> a = UIntPoly::from_vec(p, {1_z, 2_z, 2_z});
RCP<const UIntPoly> b = UIntPoly::from_vec(s, {1_z, 2_z, 2_z});
RCP<const UIntPoly> c = UIntPoly::from_vec(sinx, {1_z, 2_z, 2_z});
RCP<const UIntPoly> d = UIntPoly::from_vec(t, {1_z, 2_z, 2_z});

REQUIRE(a->__str__() == "2*2**(2*x) + 2*2**x + 1");
REQUIRE(b->__str__() == "2*x + 2*x**(1/2) + 1");
REQUIRE(c->__str__() == "2*sin(x)**2 + 2*sin(x) + 1");
REQUIRE(d->__str__() == "2*x**3 + 2*x**(3/2) + 1");
Isuru Fernando
@isuruf
Jun 21 2016 11:37
Looks good to me
Srajan Garg
@srajangarg
Jun 21 2016 14:15
@isuruf What exactly are galois fields, does it make sense for it to have an eval method. I was thinking of making it inherit from UIntPolyBase instead of UPolyBase. Some things can be made common I think.
Srajan Garg
@srajangarg
Jun 21 2016 14:21
I read about fields (very preliminarily), why does it inherit from uni polys?
Isuru Fernando
@isuruf
Jun 21 2016 15:20
@nishnik, can you comment?
Srajan Garg
@srajangarg
Jun 21 2016 17:20
Why does Mul store a map from basic to basic?
Shouldn't say x2y3x^2y^3 be stored as mul_set = {Pow(x,2), Pow(y,3)} instead of mul_map = {{x,2}, {y,3}}
In this way Mul is interanlly representing Pows
Mul right now is basically an ordered set of Pow. Why was it decided to keep it this way?
Isuru Fernando
@isuruf
Jun 21 2016 17:22
For example you want to multiply x^2*y^3 by x. What you can do is find x in the dictionary in O(log(n)) time or if it is a vector in O(n) time
Srajan Garg
@srajangarg
Jun 21 2016 17:29
Another implementation could be just adding x to the set. But I see your point. Why not std::set<Pow>?
Same can be achieved
Isuru Fernando
@isuruf
Jun 21 2016 17:30
How do you find x in std::set<Pow> ?
Srajan Garg
@srajangarg
Jun 21 2016 17:30
Right
Srajan Garg
@srajangarg
Jun 21 2016 17:47
Say I construct poly a = UIntPoly::from_basic(x + sqrt(x) + 1)
And the constructed poly has var = sqrt(x) and dict = {{0,1}, {1,1}, {2,1}}
And another poly b = UIntPoly::from_basic(x + 1), with var = x and dict = {{0,1}, {1,1}}
How will add_poly(a, b) be handled?
In [23]: a = Poly(sqrt(x) + 1)
Out[23]: Poly(sqrt(x) + 1, sqrt(x), domain='ZZ')
In [24]: b = Poly(x + 1)
Out[24]: Poly(x + 1, x, domain='ZZ')

In [26]: a + b
Out[26]: Poly(sqrt(x) + x + 2, sqrt(x), x, domain='ZZ')
Looks like sympy doesn't do it as well. Hmm
Isuru Fernando
@isuruf
Jun 21 2016 17:55
SymPy assumes that the generators are either equal or independent, which I think is a good assumption.
Srajan Garg
@srajangarg
Jun 21 2016 17:58
In [30]: Poly(x + x**Rational(1,3) + 1)
Out[30]: Poly(x + x**(1/3) + 1, x, x**(1/3), domain='ZZ')
Do we want these simplifications (not done by sympy)
Isuru Fernando
@isuruf
Jun 21 2016 17:59
Isn't that the output by SymPy?
Srajan Garg
@srajangarg
Jun 21 2016 18:00
Yes
I meant, sympy didn't do the simplification. It treats x and x**(1/3)as separate generators
Isuru Fernando
@isuruf
Jun 21 2016 18:01
That's fine. We can revisit if a need arises
Srajan Garg
@srajangarg
Jun 21 2016 18:02
Also, did you have a look at the printing issue I raised in the sympy chat. I changed symengine code to give what I expected. Should I revert it, or it's fine?
Isuru Fernando
@isuruf
Jun 21 2016 18:05
@asmeurer has a point. It shows that x**(1/3) is a generator