vermaseren / form

The FORM project for symbolic manipulation of very big expressions
GNU General Public License v3.0
982 stars 118 forks source link

rational numbers in C output #374

Open FedericoBuccioni opened 3 years ago

FedericoBuccioni commented 3 years ago

Dear Form developers,

I am using Form to produce optimised C code. I am wondering if there's a way to write rational numbers inside a generic function instead of division of two floating point numbers. Example: I might get in output 17./3. but I'd rather need something like div(17,3). What I really need actually, is to make sure that the division is valid to arbitrary numerical precision instead of only double precision, so "div" would perform a cast for me. Any suggestions?

Thanks for your help!

Federico

jodavies commented 3 years ago

polyratfun should achieve this for you? For example,

CFunction div;               
Symbol x,y;                  
Local test = 17/3*x + 17/4*y;
.sort                        

PolyRatFun div;              
Print +s;                    
.end                         

gives

test =
    + y*div(17,4)
    + x*div(17,3)
   ;
vermaseren commented 3 years ago

If you do not use the optimised version of the output, the solution of Josh is simplest. There is another way that is more laborious, but more powerful: using the dictionaries feature. This assumes though that you do not have extremely many different integers or fractions. It was mainly designed for having code that was independent of switching between verious default precisions. But with slight modifications of the examples you can make the numbers or fractions into arbitrary precision objects.

BTW. For certain numerical programs, the 5.0 version that is currently being constructed has arbitrary precision floating point built in. But to make it into a full fledged feature does not seem doable currently. It is more intended for trying out algorithms and for application of algorithms like the one presented by Francis Brown for the decomposition of motivic multiple zeta values. It is aboslutely not clear yet where this will lead to in the future.

On 21 Jan 2021, at 15:52, FedericoBuccioni notifications@github.com wrote:

Dear Form developers,

I am using Form to produce optimised C code. I am wondering if there's a way to write rational numbers inside a generic function instead of division of two floating point numbers. Example: I might get in output 17/3 but I'd rather need something like div(17,3). What I really need actually, is to make sure that the division is valid to arbitrary numerical precision instead of only double precision, so "div" would perform a cast for me. Any suggestions?

Thanks for your help!

Federico

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/374, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJPCEXEHQZGVZUWM6K4HXLS3A5TPANCNFSM4WM7ULFA.

FedericoBuccioni commented 3 years ago

Hi Joshua,

thanks a lot for you reply. However, I am possibly trying to achieve something else. Consider the following:

cf div;
s x,y;

l test = 17/3*x + 17/4*x*y^2 + 11/5*y;
.sort
PolyRatFun div;
.sort
Format O2;
.sort
Format C;
ExtraSymbols,array,z;
#optimize test
#write <test.cpp> "%O"
#write <test.cpp> "%e " test
.end

The output of this will be:

z[1]=div(11,5);
z[2]=div(17,3);
z[3]=div(17,4);
z[4]=z[3]*pow(y,2);
z[4]=z[4] + z[2];
z[4]=x*z[4];
z[5]=z[1]*y;

z[4]*div(1,1) + z[5]*div(1,1);

thus the two "problems" I see is that so on one side, I think Form it's trying to optimise also wrt "div", which ideally I'd perform inline and I think this approach could generate pretty large "z" arrays if my expression is more complicated. Maybe, I am just asking too much or just the wrong question.

jodavies commented 3 years ago

Another option is to use the optimisation in the usual way, and make a regex replacement of number/number afterwards.

FedericoBuccioni commented 3 years ago

Dear Jos,

thanks for your suggestion, but as you say I have indeed a pretty large set of rational numbers, so the Dictionary solution, although elegant, might be a bit time consuming I reckon. However, it's great news to hear about the new feature of Form 5.0!

@jodavies : that's indeed what I went for in the end, usual optimisation + regex replacement. Thus thanks again for your suggestion!