Is GiNaC really that dirty?

Christian Bauer cbauer at student.physik.uni-mainz.de
Tue Jul 17 14:02:19 CEST 2001


Hi!

On Tue, Jul 17, 2001 at 12:28:13PM +0200, Chris Dams wrote:
> To be more concrete, I want to write the function
> 
> 	ex checkdeg(ex f,ex var,int n)
> 
> which expects that *f* is a polynomial in expanded form in a variable in
> *var* and perhaps other variables. The return value is the same polynomial
> except that all terms in which *var* occurs in a power higher than *n* are
> discarded.

ex e;
for (int i=f.ldegree(var); i<n; i++)
  e += f.coeff(var, i) * pow(var, i);

If your polynomials have lots of terms, it is more efficient to write

exvector ev;
ev.reserve(n - f.ldegree(var) - 1);
for (int i=f.ldegree(var); i<n; i++)
  ev.push_back(f.coeff(var, i) * pow(var, i));
ex e = add(ev);

> struct Checkdeg:public map_function
> {       ex var;
>         int n;
>         ex operator()(const ex&f,ex v,int nint)
>         {       var=v;
>                 n=nint;
>                 return (*this)(f);
>         }
>         ex operator()(const ex&f)
> 	{
> 		... Here comes the code that actually does something ...
> 	}
> } checkdeg;

struct Checkdeg:public map_function
{
  ex var;
  int n;

  Checkdeg(const ex & var_, int n_) : var(var_), n(n_) {}

  ex operator()(const ex & f)
  {
    if (is_ex_exactly_of_type(f, add) || is_ex_exactly_of_type(f, mul))
      return f.map(*this);
    else if (f.is_equal(var) && n <= 1
          || is_ex_exactly_of_type(f, power) && f.op(0).is_equal(var) && f.op(1) >= n)
      return 0;
    else
      return f;
  }
};

> which looks somewhat queer. I really would like to be able to say
> something like
> 
> 	return f.map(*this)(var,n)

Checkdeg mapper(var, n);
return mapper(f);

> I really cannot imagine any reason whatsoever why not to automatically
> consider something that is not a product as a product with a single factor
> in patern matching against a product.

It would make the pattern matching code much more complicated.

> The manual mentions something like ten times that one may not use the
> pattern *pow(var,wild(1))* to match the expression *var*. Why on earth
> not?

The pattern matching is purely syntactic, which is also mentioned 10 times
in the manual. It's designed that way. It's not intended to be smart.

> Why does the *.find* method return
> the entire match expression, why not simply the thing that is equal to the
> wildcard.

a) Because the find() output can be directly used as input to collect(),
   which was the reason for implementing find() in the first place.
b) It would actually make the output more difficult to parse, because it
   would have to look something like
     {{$2==x,$0==sin(y)},{$2==z,$0==sin(y^2)},...}
   Remember that wildcards don't have to have numbered consecutively.

> In my opinion the user can generally be expected to know the expression
> againts which he matches, so why does he have to dissemine that one again
> when he reads the result from the match?

Because you are using it in a way that is not completely appropriate to the
task (i.e. there are better ways, see above, and so there's no need to force
the use of find() here).

> advantage is that I don't need to know that the exponent of a power is
> stored in *.op(1)*, which I really don't want to and shouldn't need to
> know as an ordinary user.

You do want to know that because it's the official way to access the base
and exponent of a power expression.

Bye,
Christian

-- 
  / Coding on PowerPC and proud of it
\/ http://www.uni-mainz.de/~bauec002/



More information about the GiNaC-list mailing list