These are chat archives for symengine/symengine

7th
Nov 2015
Ralf Stephan
@rwst
Nov 07 2015 07:33

And this is the comparison in the multivariate case:

ralf@ark:~/series-benchmark> Singular
                     SINGULAR                                 /  Development
 A Computer Algebra System for Polynomial Computations       /   version 4.0.2
> ring r=0,(x,y,z,t),dp;
> poly f=(1+x+y+z+t)^20
> size(f);
10626
> poly p = f*(f+1);
> timer;
45
> p = f*(f+1);
> timer;
90
> size(p);
135751

So, 45 seconds for fateman1 without conversion from Singular.

 4/29 Test  #4: fateman1_perf .......................   Passed    0.61 sec
 5/29 Test  #5: fateman1_dynamic_perf ...............   Passed    1.30 sec
 6/29 Test  #6: fateman1_rational_perf ..............   Passed    0.67 sec
 7/29 Test  #7: fateman1_unpacked_perf ..............   Passed    1.76 sec
 8/29 Test  #8: fateman1_unpacked_truncation_perf ...   Passed    1.67 sec

So, piranha is far ahead of Singular in the multivariate case.

Francesco Biscani
@bluescarni
Nov 07 2015 16:55
@certik @isuruf @rwst Sorry for not replying here before, haven't used gitter in a while
So in order:
@certik You are correct, Piranha does not offer any polynomial GCD/division/Groebner basis functionality at the moment. I'd love to have that in, but so far I have not had the time to look deeply into it and it seems like a huge project
@certik Correct, MSVC does not support enough C++11 to compile Piranha. It will hopefully get there eventually. You can probably compile some bits of it though (maybe the integer class will work)
@certik @rwst There's a lot of overhead going on in Piranha for small operands, which I have not looked into optimising yet. On top of that, for univariate computations, the FLINT representation will be inherently better, so even if I spend time optimising small operands I am fairly certain we will never get close to FLINT for univariate polynomials
With that said, I am all up for improving performance on small operands
I can spend some time on it, I think the benchmarks @rwst posted are a good starting point
Francesco Biscani
@bluescarni
Nov 07 2015 17:00
Most optimisation work so far has been for large operands and multithreading
Francesco Biscani
@bluescarni
Nov 07 2015 17:31
@rwst Yes the Python bindings use a lot of memory. It gets a bit better with clang, and I am currently looking into replacing Boost.Python with pybind11:
this is basically a rewrite of Boost.Python in C++11. My hope is that it will use much less memory as it can avoid all the pre-processor tricks and the template/overload bloat that is necessary to implement Boost.Python in C++03
harakas
@harakas
Nov 07 2015 18:38
Hello. What is the status of symengine.py? It failed to compile with the master heads. I did manage to get it compiling by uncommenting FunctionWrapper.
Isuru Fernando
@isuruf
Nov 07 2015 18:43
@harakas, yes, I'm working on that.
We test symengine.py with a fixed commit https://github.com/isuruf/symengine.py/blob/pynumber/.travis.yml#L111
and then update it from time to time
And fix API breaks from symengine/symengine
Isuru Fernando
@isuruf
Nov 07 2015 18:52

@bluescarni, quick question. How do I define a user-defined literal and make use of namespaces? I followed http://codereview.stackexchange.com/questions/49502/user-defined-string-literals-and-namespace-use
and did it like this,

inline namespace literals
{
    integer_class operator "" _z(const char*str, const size_t size)
    {
        return SymEngine::integer_class(std::string{str, str + size});
    }
}

I get errors saying _z is defined in multiple places (In all .cpp files where I include that header)

harakas
@harakas
Nov 07 2015 19:01
Thank you, @isuruf. Another question. In c++, why can't I do stuff like auto x = symbol("x"); ... ; auto res = x*y+z;, that is why are these missing:
  RCP<const Basic> operator+(const RCP<const Basic> &a, const RCP<const Basic> &b) { return add(a, b); }
  RCP<const Basic> operator-(const RCP<const Basic> &a, const RCP<const Basic> &b) { return sub(a, b); }
  RCP<const Basic> operator*(const RCP<const Basic> &a, const RCP<const Basic> &b) { return mul(a, b); }
  RCP<const Basic> operator/(const RCP<const Basic> &a, const RCP<const Basic> &b) { return div(a, b); }
harakas
@harakas
Nov 07 2015 19:06
I don't understand why I "should not" do these overloads. Or does RCP have some required functionality under these +, -, * and / operators? If so, you should switch to a different smart pointer type that does not have such limitations.
Isuru Fernando
@isuruf
Nov 07 2015 19:20
RCP already has == and != operators. If we had +, -, * and / operators then users might think a==b is the same as eq(a, b) and that's not what is happening, but that's just my opinion. @certik what do you think?
Francesco Biscani
@bluescarni
Nov 07 2015 19:22
@isuruf: is that intended to be a literal that you use only in tests or more general?
Isuru Fernando
@isuruf
Nov 07 2015 19:23
@bluescarni, more general
Francesco Biscani
@bluescarni
Nov 07 2015 19:23
Thinking of it, I am not so sure how to overload literals... maybe it would be best to introduce a new one
that just calls the other two
is the decision on which integer class to use to be taken at compile time with an ifdef or similar?
or are they supposed to coexist?
Isuru Fernando
@isuruf
Nov 07 2015 19:25
It's not overloading. I'm introducing a new literal in SymEngine::literals namespace.
Compile time
Francesco Biscani
@bluescarni
Nov 07 2015 19:26
I am thinking that you cannot really overload literals, because any literal takes the same input arguments and only the return type changes
it would be like overloading double foo(int) with int foo(int)... can't really do that can you
Isuru Fernando
@isuruf
Nov 07 2015 19:27
Ah. So even if it is in another namespace, you can't have the same return type?
Francesco Biscani
@bluescarni
Nov 07 2015 19:30
Mhmm.. it's tricky.. it depends on where you call it from. If you use it inside the symengine namespace, I think the literal defined in the symengine::literals namespace will be always picked up first
it has to do with how unqualified function calls are resolved depending on the context
how about defining the _mpz literal like this:
This message was deleted
harakas
@harakas
Nov 07 2015 19:31
Many many years ago I once implemented my own gmp/c++ wrapper with smart pointers, where == and != worked as one would expect. Technically, there should not be a problem.
Francesco Biscani
@bluescarni
Nov 07 2015 19:33
namespace SymEngine { namespace literals {

#if define(SYMENGINE_USE_PIRANHA_INTEGER)
piranha::integer operator "" _mpz(const char *s)
{
    return piranha::literals::_z(s);
}

#else

mpz_class operator "" _mpz(const char *s)
{
    return mpz_class(s);
}

#endif

}}
something like this anyway
not sure about the syntax to call piranha's literal, but you can just replace it with return piranha::integer(s); if you want
it's the same thing
Isuru Fernando
@isuruf
Nov 07 2015 19:36
@bluescarni, I think that's not the problem. I get the same error when the literal is changed from _z to others like _symengine
Francesco Biscani
@bluescarni
Nov 07 2015 19:36
can you post a snippet somewhere?
Isuru Fernando
@isuruf
Nov 07 2015 19:38
[  8%] Built target teuchos
Linking CXX shared library libsymengine.so
CMakeFiles/symengine.dir/dict.cpp.o: In function `SymEngine::literals::operator"" _symengine(char const*)':
dict.cpp:(.text+0x13b0): multiple definition of `SymEngine::literals::operator"" _symengine(char const*)'
CMakeFiles/symengine.dir/basic.cpp.o:basic.cpp:(.text+0x880): first defined here
CMakeFiles/symengine.dir/symbol.cpp.o: In function `SymEngine::literals::operator"" _symengine(char const*)':
symbol.cpp:(.text+0x1c0): multiple definition of `SymEngine::literals::operator"" _symengine(char const*)'
CMakeFiles/symengine.dir/basic.cpp.o:basic.cpp:(.text+0x880): first defined here
CMakeFiles/symengine.dir/number.cpp.o: In function `SymEngine::literals::operator"" _symengine(char const*)':
number.cpp:(.text+0x50): multiple definition of `SymEngine::literals::operator"" _symengine(char const*)'
CMakeFiles/symengine.dir/basic.cpp.o:basic.cpp:(.text+0x880): first defined here
I've added the definition to a header file called mp_class.h and imported at dict.h which is imported in all headers
Francesco Biscani
@bluescarni
Nov 07 2015 19:38
did you mark it inline?
Isuru Fernando
@isuruf
Nov 07 2015 19:38
yes
Francesco Biscani
@bluescarni
Nov 07 2015 19:38
I mean the literal operator
Isuru Fernando
@isuruf
Nov 07 2015 19:40
That fixed it. Thanks.
Why is the inline operator important?
Francesco Biscani
@bluescarni
Nov 07 2015 19:41
sure np... the literal is just another function, when you use it it gets quite literally replaced by the compiler with a call to that function
so like any other function call, if it is not marked inline and you use it in multiple translation units, you will get a duplicate symbol
by marking it inline you are instructing the compiler to insert a copy of the body of the function, rather than a function call
the same thing happens with operator overloading (which are also just syntactic sugar for function calls)
Francesco Biscani
@bluescarni
Nov 07 2015 19:49
to expand a bit: imagine you have a function whose definition and implementation are both in a header called foo.h
when you include foo.h in foo.cpp, the compiler will compile the implementation of the function and typically export it in the produced object file foo.o
This means that foo.o is saying: hey, I have an implementation of your function available, just link to me and you can use it!
Isuru Fernando
@isuruf
Nov 07 2015 19:51
Right, when that header is used in several .cpp files, multiple definitions
Francesco Biscani
@bluescarni
Nov 07 2015 19:51
so if multiple object files advertise the same thing, a clash will happen
yes
if you mark it inline, the function will not appear in the symbol table of foo.o