Hello, On Tue, Feb 24, 2009 at 10:07:12AM -0500, Jeremy Jay wrote:
It's not "intuitive" because I can see a plain single "1" when i print the poly, and I can call subs(1==q) on the poly with no errors, but when I print the poly again it is unchanged.
It's never going to be "what you see is what you get" (see the example in M.........a I've given in a previous mail).
If I were to print your first example as written, I would not see a "4" in the output and I would not expect anything to be substituted. If I wanted to make sure I got the 4, I would have to call expand or whatever appropriately, before the substitution.
In the second example I would expect it to come out to (x^2+A*x+A). I see 4s and I'm substituting As in their place. If I don't want the 4x changed I'll have to do some extra work myself, but I don't expect GiNaC to differentiate between the 4s I see.
I think any of these cases are very "intuitive" for any programmer with any experience with any pattern matching.
Even for strings there are a number of different matching rules (cf. `greedy matching' versus `non-greedy matching'). Obviously, there are much more different ways to define matching rules for mathematical expressions. And for every such definition there are people who like it (for a good reason) and those who hate it (for a good reason, too!).
A substitution is just that, a substitution, and it is not "well-defined" mathematically and I don't really see any reason for it to be as rigorous as you imply.
Mathematical definitions help to avoid confusion, because typically such definitions avoid highly subjective notions (such as `intuitive'). That said, I don't know any formal definition of pattern matching (for mathematical expressions). All mathematical software I know of operates on internal representation. At best, that representation and matching rules are documented, but that's it.
If someone wants to do silly things like replace 4s with As, let him!
No problem. The code below does something like that. However, it replaces _all_ '4s with As'. #include <ginac/ginac.h> #include <iostream> using namespace std; using namespace GiNaC; struct subs_silly : public map_function { ex patt; ex repl; ex operator()(const ex& e) { if (is_a<add>(e) || is_a<mul>(e)) return e.map(*this); if (is_a<power>(e)) { return power(e.op(0).map(*this), e.op(1).map(*this)); } if (e.is_equal(patt)) return repl; else return e; } }; int main(int argc, char** argv) { symbol x("x"), y("y"), q("q"); ex e = y*pow(x, 2) + 1; subs_silly se; se.patt = ex(1); se.repl = q; cout << e << " => "; e = se(e); cout << e << endl; // prints: 1+x^2*y => q+x^2*y return 0; }
Alexei made his point, yes, but I don't see how it is "correct." He said that the semantics of a simple substitution rely upon the internal representation of the polynomial -- although there is no documentation on this point anywhere on the website.
That's not quite true. The internal documentation is somewhat documented in the tutorial (Appendix A.2, titled `Internal representation of products and sums'). Also, GiNaC provides the `tree' printing context, which outputs the internal representation of expression: #include <ginac/ginac.h> #include <iostream> using namespace std; using namespace GiNaC; int main(int argc, char** argv) { symbol x("x"), y("y"); ex e = y*pow(x, 2) + 1; cout << "Internal representation of the expression \"" << e << "\" is: " << endl; cout << tree << e << endl << dflt; return 0; } Best regards, Alexei