| Karim Belabas on Wed, 07 Aug 2013 22:42:52 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Re: Variable checker |
* Dirk Laurie [2013-08-07 16:26]:
> I have written a routine that for a given expression checks whether
> it contains any variables that are not in a given list. It works.
>
> Only problem is, I don't understand why.
>
> { foreign(expr,vars) =
> if (type(expr)=="t_RFRAC",
> return(foreign(numerator(expr)) || foreign(denominator(expr))));
> my(var=trap(,,variable(expr)));
> print(expr", "var);
> if(!var, return(0)); \\ expr is scalar
> if(subst(vars,var,0)==vars, return(var)); \\ var is not present in vars
> foreign(polcoeff(expr,0),vars) }
Why do you only check the degree 0 coefficient ?
? foreign(x^3 + b*x^2 + a*x, [x,a])
%1 = 0
Independently, if I build the expression in a slightly different way, it
will no longer work:
? foreign(Pol([1,a,b]), [x,a])
%2 = 0
> ? foreign(x^2+a*x+b,[x,b])
> x^2 + a*x + b, x
> b, a
> %2 = a
>
> The value of 'expr' on the recursive call is 'b'. There's no 'a' in
> it. Yet variable(expr) returns 'a'.
>
> I'm grateful it does. But it baffles me.
In 2.6.*, you can use
dbg_x(expr) \\ programmatic equivalent of \x applied to 'expr'
to debug such problems. In the recursive call, it prints
[&=00007ffff64de508] POL(lg=3):1400000000000003 (+,varn=24):4006000000000000 00007ffff64de4e8
coef of degree 0 = [&=00007ffff64de4e8] POL(lg=4):1400000000000004 (+,varn=25):4006400000000000 00000000007dd620 00007ffff64de4d0
coef of degree 0 = gen_0
coef of degree 1 = [&=00007ffff64de4d0] INT(lg=3):0200000000000003 (+,lgefint=3):4000000000000003 0000000000000001
which is a little hard to read, but corresponds to a t_POL with t_POL
coefficients, actually equal to
(0 + 1*b) * a^0
so variable(expr) is correct in returning 'a'.
My approach for this, would be to write a function
variables(expr)
returning a Set() of all variables occuring in 'expr'. Then one could use
setminus(variables(expr), Set(vars))
(or 'vars' by itself if we can assume that it's already a Set).
Using 2.6.* syntax (iferr() instead of trap(), now deprecated...) :
variables(expr) =
{ my(v, L);
if (type(expr) == "t_RFRAC",
my (n = numerator(expr), d = denominator(expr));
return (setunion(variables(n), variables(d)))
);
v = Vec(expr); if (v === [expr], return ([]) /*scalar*/);
L = iferr([variable(expr)], E, []);
for (i = 1, #v, L = setunion(L, variables(v[i])));
L;
}
foreign(expr, vars) = setminus(variables(expr), Set(vars));
? expr = [x^2+a*x, 1/t; u + O(z), "STR"];
? variables(expr)
%2 = [x, z, t, a, u]
? foreign(expr, [a,u,v])
%3 = [x, z, t]
(Quick, mostly untested, hack. Possibly not entirely foolproof :-)
Cheers,
K.B.
P.S. it's awkward to have variable() raise an error when no variable can be
associated to the argument. It would be more useful to have it return a
sentinel value such as '0'.
--
Karim Belabas, IMB (UMR 5251) Tel: (+33) (0)5 40 00 26 17
Universite Bordeaux 1 Fax: (+33) (0)5 40 00 69 50
351, cours de la Liberation http://www.math.u-bordeaux1.fr/~kbelabas/
F-33405 Talence (France) http://pari.math.u-bordeaux1.fr/ [PARI/GP]
`