[GiNaC-list] feature request

Marko Riedel riedelmo at mathematik.uni-stuttgart.de
Wed Feb 22 06:29:48 CET 2023


Greetings to all.

Continuing with my GiNaC project I have noticed that there was some 
functionality missing that other software offers. In particular, I 
require **factorization of integers** and a function to compute the 
**set of divisors** of an integer. I have implemented these using basic 
math such as might be used in a freshman course. It passes all my tests, 
but it really needs an implementation from a professional mathematician. 
Maybe you can file this with other feature requests you have received. 
An excerpt from my code follows below. I hope I have understood lists 
correctly that they are doubly linked and a list append of one element 
runs in constant time.

Best regards,

Marko

lst factorizeposint(numeric n)
{
   lst result = {}, ent;

   int pot = 0;
   while(irem(n, numeric(2)).is_zero()){
     pot++; n = iquo(n, numeric(2));
   }
   if(pot > 0){
     ent = {numeric(2), pot};
     result.append(ent);
   }

   numeric q = 3;

   while(q*q <= n){
     pot = 0;
     while(irem(n, q).is_zero()){
       pot++; n = iquo(n, q);
     }
     if(pot > 0){
       ent = {q, pot};
       result.append(ent);
     }
     q += 2;
   }
   if(n > 1){
     ent = {n, numeric(1)};
     result.append(ent);
   }

   return result;
}

numeric totient(numeric n)
{
   if(n==1) return 1;

   lst pfact = factorizeposint(n); numeric result = n;

   for(lst::const_iterator it = pfact.begin();
       it != pfact.end(); ++it){
     lst ent = ex_to<lst>(*it);
     result *= numeric(1)
       -numeric(1)/ex_to<numeric>(ent.op(0));
   }

   return result;
}


lst divisors(numeric n)
{
   if (n==1) return {1};

   lst pfact = factorizeposint(n), ent;

   numeric tau(1);

   lst::const_iterator it;
   for(it = pfact.begin(); it != pfact.end(); ++it){
     ent = ex_to<lst>(*it);
     tau *= numeric(1)+ex_to<numeric>(ent.op(1));
   }

   exvector res {};
   res.resize(tau.to_int(), numeric(1));

   int sofar = 1; int pos;
   for(it = pfact.begin(); it != pfact.end(); ++it){
     pos = sofar;
     ent = ex_to<lst>(*it);
     numeric p = ex_to<numeric>(ent.op(0));
     numeric v = ex_to<numeric>(ent.op(1));
     for(numeric vv(1); vv <= v; vv++){
       for(int q = 0; q < sofar; q++){
         res[pos++] = res[q]*pow(p,vv);
       }
     }
     sofar = pos;
   }

   lst result = {};
   for(pos=0; pos<sofar; pos++)
     result.append(res[pos]);

   return result;
}



More information about the GiNaC-list mailing list