Skip to content

UC Davis Series Expansion Project Multivariable Polynomial Benchmarks

Shikhar Jaiswal edited this page Oct 30, 2016 · 2 revisions

I have written the following benchmark for assessing the speed of various implementations of the MultiviariableIntPolynomial class.

`#include <iostream>
 #include <chrono>
 #include <symengine/polynomial.h>
 #include <symengine/polynomial_multivariate.h>
using SymEngine::RCP;
using SymEngine::Symbol;
using SymEngine::symbol;
using SymEngine::MultivariateIntPolynomial;
using SymEngine::mul_mult_poly;
using SymEngine::integer_class;
using SymEngine::vec_uint;
//using SymEngine::map_uvec_mpz;
using SymEngine::umap_uvec_mpz;
using namespace SymEngine::literals;
int main()
{
    RCP<const Symbol> x = symbol("x");
    RCP<const Symbol> y = symbol("y");
    RCP<const Symbol> z = symbol("z");
    //FRPOLY benchmark sans floating-point test
//Smallnum coefficinets
RCP<const MultivariateIntPolynomial> p = MultivariateIntPolynomial::from_dict({x,y,z}, { {{0,0,0}, 1_z}, {{0,0,1}, 1_z},  {{0,1,0}, 1_z}, {{1,0,0}, 1_z}} );
auto t1 = std::chrono::high_resolution_clock::now();
RCP<const MultivariateIntPolynomial> p2 = mul_mult_poly(*p,*p);
RCP<const MultivariateIntPolynomial> p3 = mul_mult_poly(*p,*p2);
RCP<const MultivariateIntPolynomial> p4 = mul_mult_poly(*p2,*p2);
RCP<const MultivariateIntPolynomial> p7 = mul_mult_poly(*p3,*p4);
RCP<const MultivariateIntPolynomial> p8 = mul_mult_poly(*p4,*p4);
RCP<const MultivariateIntPolynomial> p15 = mul_mult_poly(*p7,*p8);
auto t2 = std::chrono::high_resolution_clock::now();
std::cout << "Smallnum: " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << "ms" << std::endl;
//Bignum coefficients
RCP<const MultivariateIntPolynomial> q = MultivariateIntPolynomial::from_dict({x,y,z}, { {{0,0,0}, 100000_z}, {{0,0,1}, 100000_z},  {{0,1,0}, 100000_z}, {{1,0,0}, 100000_z}} );
t1 = std::chrono::high_resolution_clock::now();
RCP<const MultivariateIntPolynomial> q2 = mul_mult_poly(*p,*p);
RCP<const MultivariateIntPolynomial> q3 = mul_mult_poly(*p,*p2);
RCP<const MultivariateIntPolynomial> q4 = mul_mult_poly(*p2,*p2);
RCP<const MultivariateIntPolynomial> q7 = mul_mult_poly(*p3,*p4);
RCP<const MultivariateIntPolynomial> q8 = mul_mult_poly(*p4,*p4);
RCP<const MultivariateIntPolynomial> q15 = mul_mult_poly(*p7,*p8);
t2 = std::chrono::high_resolution_clock::now();
std::cout << "Bignum: " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << "ms" << std::endl;
//Large Polynomials
RCP<const MultivariateIntPolynomial> p1 = MultivariateIntPolynomial::from_dict({x,y,z},{ {{0,0,0}, 1_z}, {{1,0,0}, 1_z}, {{0,1,0}, 1_z}, {{0,0,1}, 1_z} });
t1 = std::chrono::high_resolution_clock::now();
for (unsigned int i = 0; i < 5; i++) {
    p1 = mul_mult_poly(*p1,*p1);
}
t2 = std::chrono::high_resolution_clock::now();
std::cout << "Powers: " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << "ms" << std::endl;
std::cout << "Different Sized Polynomials" << std::endl;
unsigned int limits[] = {10,100,1000,2000};
for (unsigned int k = 0; k < 4 ; k++){
    umap_uvec_mpz d1, d2;
    int j = 0;
    for (unsigned int i = 0; i < limits[k]; i++) {
        vec_uint v1, v2;
        v1.resize(3);
        v1[0] = i;
        v1[1] = i + 1;
        v1[2] = i + 2;
        v2. resize(3);
        v2[0] = i * 2;
        v2[1] = i + 4;
        v2[2] = i / 2;
        d1.insert({std::pair<vec_uint, integer_class>(v1,1_z)});
        d2.insert({std::pair<vec_uint, integer_class>(v2,1_z)});
    }
RCP<const MultivariateIntPolynomial> pp1 = MultivariateIntPolynomial::from_dict({x,y,z},std::move(d1));
RCP<const MultivariateIntPolynomial> pp2 = MultivariateIntPolynomial::from_dict({x,y,z},std::move(d2));
t1 = std::chrono::high_resolution_clock::now();
RCP<const MultivariateIntPolynomial> pp3 = mul_mult_poly(*pp1,*pp2);
t2 = std::chrono::high_resolution_clock::now();
std::cout << limits[k] << " terms by " << limits[k] << " terms: " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << "ms" << std::endl;
}
}`

The output of this benchmark on the current unordered_map implementation is as follows:

Smallnum: 32ms
Bignum: 32ms
Powers: 1312ms
Different Sized Polynomials
10 terms by 10 terms: 0ms
100 terms by 100 terms: 37ms
1000 terms by 1000 terms: 4601ms
2000 terms by 2000 terms: 18773ms

The output of this benchmark with the unordered_map replaced with an ordered map are

Smallnum: 72ms
Bignum: 71ms
Powers: 3632ms
Different Sized Polynomials
10 terms by 10 terms: 0ms
100 terms by 100 terms: 62ms
1000 terms by 1000 terms: 8918ms
2000 terms by 2000 terms: 40530ms
Clone this wiki locally