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] `