Bill Allombert on Sat, 08 Dec 2018 14:15:21 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [BUG 2.5.0–CURRENT] taille() and taille2() are mixed up in pariold.h


On Fri, Dec 07, 2018 at 08:23:36PM -0800, Ilya Zakharevich wrote:
> P.S.  My conjecture now is that the major missing part is “How to make
>       «type=I» and «type=E» arguments”.  (But, as I explained above, I
>       cannot check that “the rest” is working already…) 
> 
>       Suppose I have a C function
>         GEN mysummand(GEN I, void *mydata);
>       It is completely unclear how can I make out of it something to
>       pass to (e.g.) somme() to make an analogue of
>         sum(I=1,3,mysummand(I))

Hello Ilya,

To help you to upgrade, I join a program that should do what you want.

1) use pari_add_module to add your functions to GP.
  pari_add_module(functions_ilya);

2) use strtoclosure to create the partial function as t_CLOSURE object
  fun = strtoclosure("_ilya_mysummand",1,stoi((long)&mydata));
This returns a t_CLOSURE x -> mysummand(x, &mydata)

At this point you can use the t_CLOSURE directly in functions like
apply that need a true closure (code "G" or "J")

3) for functions like sum that need a inline closure (code "E" or "I"),
you need to create a gadget that will inline your closure inside the
sum. The simplest is to use the GP compiler:
  sum_gadget = gp_read_str("(a,b,C)->sum(i=a,b,C(i))")
and then use closure_callgenall to evaluate it with C set to your
closure.
  s = closure_callgenall(sum_gadget, 3, stoi(1), stoi(3), fun);

Cheers,
Bill.
#include <pari/pari.h>

struct dat
{
  long a, b;
};

GEN mysummand(GEN x, void *data)
{
  struct dat *E = (struct dat *) data;
  return addis(mulis(x,E->a),E->b);
}

entree functions_ilya[]={
  {"_ilya_mysummand",0,(void*)mysummand,11,"GL","_ilya_mysummand(x,data): ??"},
  {NULL,0,NULL,0,NULL,NULL}};

void main(void)
{
  struct dat mydata = {17,23};
  GEN fun, res, s;
  GEN sum_gadget;
  pari_init(8000000,500000);
  pari_add_module(functions_ilya);
  sum_gadget = gp_read_str("(a,b,C)->sum(i=a,b,C(i))");
  fun = strtoclosure("_ilya_mysummand",1,stoi((long)&mydata));
  res = apply0(fun, vecrangess(1,100));
  output(res);
  s = closure_callgenall(sum_gadget, 3, stoi(1), stoi(3), fun);
  output(s);
  pari_close();
}