Mathematica has a syntax "/." or "ReplaceAll" of the general form
expr /. {a->b}
which, as I understand it, means "replace all instances of symbol a
appearing in expr with symbol b".
In many fields of practical engineering one makes extensive use of
so-called "phasor analysis" to solve systems of coupled linear
differential equations with real coefficients and sinusoidal driving
terms. The outcome of this analysis is a "transfer function" f in the
form of a rational polynomial with real terms except for explicit
factors of I = Sqrt[-1]. It's often useful to have in addition the
complex conjugate of that transfer function ("fStar"), which, since all
other parameters are purely real, can be obtained by replacing I by -I
in the transfer function.
So, with this prolog, let's try this last step using Mathematica on a
simple example, e.g., the test input and resulting output:
Clear[a,b,c,d,f,fStar]; f = (a+I b)/(c+I d);
fStar = f /. {I->-I}; {f, fStar} // Simplify
{(a+I b)/(c+I d), (a-I b)/(c-I d)}
Looks good -- but let's try instead:
Clear[a,b,c,d,f,fStar]; f=(a+I b)/(c-I d);
fStar = f/.{I->-I}; {f1,f1Star} // Simplify
{(a+I b)/(c-I d),(a-I b)/(c-I d)}
which gives a result that certainly appears to be dead wrong.
My question is: Does this sort of thing -- this sort of problem --
happen also in other symbolic algebra packages? Or is this in some way
a bizarre (and IMHO highly dysfunctional, not to say destructive)
behavior peculiar to Mathematica?
< long story>
> My question is: Does this sort of thing -- this sort of problem --
> happen also in other symbolic algebra packages?
1. Are there bugs in other symbolic algebra packages? Yes.
2. Is THIS particular bug in other symbolic algebra packages? Not in one
that I tried (Maxima). But maybe in others, for the reasons given below.
Or is this in some way
> a bizarre (and IMHO highly dysfunctional, not to say destructive)
> behavior peculiar to Mathematica?
You should post it on the Mathematica list and see what response you get
there.
I find that often when I post what I think of as absurd (mathematically
speaking) results, at least one Mathematica fan will say "We meant to
do that."
(compare with
http://www.youtube.com/watch?v=vJXU7EVXs2A )
In the particular case you are looking at, consider running FullForm[]
on your expressions. You will then find that
FullForm[c-I*d] = Plus[c, Times[Complex[0,-1],d]]
and that FullForm[I] is Complex[0,1].
Thus there is no occurrence of Complex[0,1] in c-I*d.
you could try f/. {I->-I, -I->I}
or you could use a computer algebra system that knows enough to do this
automatically.
Another example of this bug (or feature) in Mathematica is
1/x^2 /. x^2-> Y^4
which you would naturally expect to result in 1/y^4.
But no, it is unchanged because there is no occurrence of Power[x,2]
there. Only Power[x,-2].
Cheers.
RJF
This bug (or feature) is absent in Derive 6.10, the system I am using:
f := (a + #i*b)/(c - #i*d)
fStar := subst(f, #i, -#i)
[f,fStar]
[a*c/(c^2 + d^2) - b*d/(c^2 + d^2)
+ #i*(a*d/(c^2 + d^2) + b*c/(c^2 + d^2)),
a*c/(c^2 + d^2) - b*d/(c^2 + d^2)
- #i*(a*d/(c^2 + d^2) + b*c/(c^2 + d^2))]
I would say that not many of the other Computer Algebra systems show the
behavior you have in Mathematica here. But there are annoying bugs in
Derive 6.10 too (I haven't heard anyone calling them features).
>
> Another example of this bug (or feature) in Mathematica is
>
> 1/x^2 /. x^2-> Y^4
>
> which you would naturally expect to result in 1/y^4.
Since Richard Fateman is mentioning it:
subst(1/x^2, x^2, y^4)
1/x^2
Here Derive behaves like Mathematica, presumably for a similar reason:
The subexpression x^2 is not actually present in the expression 1/x^2. I
am calling this one a bug because 1/x^2 (and x^(-2)) simplifies to
1/x^2, and because the internal representation is reported to be:
string(1/x^2)
["/", 1, x^2]
On the other hand (this is not really surprising):
subst(1/x^2, x^(-2), y^(-4))
1/y^4
subst(1/x^2, 1/x^2, 1/y^4)
1/y^4
Apparently, one programmer didn't know what the other was doing, or what
he himself had done years before.
Martin.
> < long story>
>
> > My question is: Does this problem occur also in other
> > symbolic algebra packages? Or is this (IMHO quite
> > dysfunctional) behavior peculiar to Mathematica?
and Richard Fateman <fat...@cs.berkeley.edu> replied:
> You should post it on the Mathematica list and see what
> response you get there.
>
> I find that often when I post what I think of as absurd (mathematically
> speaking) results, at least one Mathematica fan will say "We meant to
> do that."
This particular misbehavior was in fact discussed at some length on
c.s-s.m.m some time back.
As often happens on that group, there were multiple explanations of
_why_ this (IMHO dysfunctional) misbehavior occurs, and multiple
suggestions of alternative ways to accomplish the intended result.
But I would say that no one really wanted to concede the fact that this
was (again, IMHO) a clearly dysfunctional behavior.
> you could try f /. {I->-I, -I->I}, or use a computer algebra system
> that knows enough to do this automatically.
I don't believe this concept appeared in the Mathematica newsgroup
discussion, but it would seem to avoid the problem behavior.
What is f1 and f1Star above in the second example?
Where did they come from? I think you mean just "f" and "fstar"
But to your point, would'nt this simpler example do it?
Clear[a, b, f]
f = a - I b
f /. I -> -I
a - I*b
And what you really expected to see is
f = a - (-I)*b
a + I*b
This is not a bug.
Mathematica, for replacements, does not use what shows up on the screen, but
uses the FullForm of the expression. What happens above is that NO
replacement has occured.
To make replacement involving complex numbers, use the fullForm:
Clear[a, b, f]
f = a - I*b;
f /. Complex[a_, b_] -> Complex[a, -b]
a + I*b
So, in your orginal example, write
fStar = f /. {Complex[a1_, b1_] -> Complex[a1, -b1]};
And it should be OK now.
--Nasser
>
> As often happens on that group, there were multiple explanations of
> _why_ this (IMHO dysfunctional) misbehavior occurs, and multiple
> suggestions of alternative ways to accomplish the intended result.
>
In Mathematica, there is almost always more than 10 different ways to do the
same thing.
You know you are becoming close to be a Mathematica expert when you have
some good reason for choosing one alternative over the other ;)
As to the dysfunctional misbehavior: The problem is that Mathematica uses
the FullForm internally for all the symbolic manipulation.
Almost always, the FullForm and what shows on the screen follow along just
fine, but for few cases, such as one here, one need to check the FullForm to
be sure the replacement is correct.
I guess that the only way to get out of situation would be to use 1:1
mapping of the expression that gets displayed on the screen for the internal
representation of the expressions, so there is no "misalignment" at all. I
do not know if this would be possible in all cases, but I think this is
something that gets done very early on in the design of a CAS system, and
too late for Mathematica to do anything about this now. Just have to
remember these things whenever you are using Mathematica.
--Nasser
In Mathematica, at least, this can be overcome with a combination of
Hold and ReleaseHold:
----------------
In[2]:= ReleaseHold[Hold[1/Complex[0, 1]] /.
Complex[0, 1] -> x]
Out[2]= 1/x
----------------
When viewed this way, it's evident that there are plenty of other
similiar situations, like the one that Richard presented. Here's
another:
----------------
In[3]:= (x^2)/x /. x^2 -> y
Out[3]= x
----------------
Maxima behaves in the same way:
----------------
Maxima 5.19.2 http://maxima.sourceforge.net
Using Lisp SBCL 1.0.30
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) subst(x^2 = y, (x^2)/x);
(%o1) x
-----------------
I don't think I would call this a bug or a feature. I would, however,
acknowledge that symbolic manipulation is a bit tricky in general.
Mark McClure
>
> This is not a bug.
>
>
For AES it is a bug, and it can and should be fixed. See below.
Indeed, Macsyma used to do such things, and it was fixed. (I think I
fixed it in perhaps
1968 or so, in the "subst" functionality.)
It is a bug because any person reasonably familiar with mathematics
expects a behavior that is different from the behavior of Mathematica.
Furthermore, the proper behavior can be programmed.
How can it be fixed?
By taking a command that looks like "substitute -I for I in
expression z" and noticing that it probably also means "substitute I
for -I in expression z". There are not many similar screwball cases,
and they are easily noticed.
Thus without a great deal of effort one can write a program, let us call
it CorrectSubstitution[] in Mathematica that fixes this and similar bugs.
I would suggest that this program be the default, and that the one that
is apparently in Mathematica now be called something like
AnalRetentiveFullFormOnlySubstitution[].
Mark McClure's objection that (x^2)/x should have a subexpression of
x^2 in it is, I think not of the same relevance. It is pretty
fundamental in computer algebra systems that expressions which are typed
in to the system, whether they are displayed first or just fed to
commands like subst are simplified (at least to some extent) first, and
that this process will potentially change the expression. In this case
changing x^2/x to x. If Mark wants a system that only parses
expressions, this can be simulated by turning off the simplifier. This
is usually a dreadful idea
.
To elaborate: any time you try to find instances of a non-trivial
subexpression (for substitution), there is a question of how you will
find them. It is clearer if you substitute sqrt(y) for x than to
substitute y for x^2. The latter makes it unclear what to do with x^3,
which might be x^3, x*y or y^(3/2). That is, finding a symbolic
constant like x is generally unambiguous, whereas the subexpression x^2
IS AMBIGUOUS in general parlance.
(Maxima's ratsubst command provides an unambiguous interpretation that
is more ambitious than syntactic substitution. It would give x*y).
In the specific case in Mathematica, the target APPEARS to be an atomic
symbolic constant, I, appropriate for substitution. But it is a
subexpression, Complex[0,1].
This is a BUG BUG BUG, and could be fixed. But only if you stop
thinking like Peewee Herman.
http://www.youtube.com/watch?v=vJXU7EVXs2A
As I predicted, and as AES pointed out. For people who reflexively
defend such dysfunctional behavior, let me just ask this: what would it
cost to do it correctly? Would it break something? Would it be an
unspeakable inefficiency?
As I have pointed out some number of times, if you can make something
behave mathematically correctly, you should do it.
I promise not to mock WRI if they follow my advice.
Cheers
>For example, we can write an expression
> that quite explicitly includes a Complex[0,1] and apply a replacement
> rule but that rule will not be applied if automatic "simplification"
> beats us to it:
> ----------------
> Mathematica 7.0 for Mac OS X x86 (64-bit)
> Copyright 1988-2009 Wolfram Research, Inc.
> In[1]:= 1/Complex[0,1] /. Complex[0,1] -> x
> Out[1]= -I
> ----------------
>
Hi Mark;
You are right, but again, this example I think is similar to the original
one. If one uses the general complex replacement rule it will work:
In[8]:= 1/Complex[0, 1] /. Complex[a_, b_] -> x
Out[8]= x
> In Mathematica, at least, this can be overcome with a combination of
> Hold and ReleaseHold:
> ----------------
> In[2]:= ReleaseHold[Hold[1/Complex[0, 1]] /.
> Complex[0, 1] -> x]
> Out[2]= 1/x
> ----------------
>
Yes, the above works. But I think if one remembers the general complex
replacement rule then then do not have to worry about using Hold etc..
> When viewed this way, it's evident that there are plenty of other
> similiar situations, like the one that Richard presented. Here's
> another:
> ----------------
> In[3]:= (x^2)/x /. x^2 -> y
> Out[3]= x
> ----------------
>
> Maxima behaves in the same way:
Yes, The above is due to automatic evaluation of (x^2)/x before the rule is
used. But I think in this case almost every CAS will work the same. I will
be suprprised if there is a CAS which will not automatically simplify x^2/x
to x.
.
> ----------------
> Maxima 5.19.2 http://maxima.sourceforge.net
> Using Lisp SBCL 1.0.30
> Distributed under the GNU Public License. See the file COPYING.
> Dedicated to the memory of William Schelter.
> The function bug_report() provides bug reporting information.
> (%i1) subst(x^2 = y, (x^2)/x);
> (%o1) x
> -----------------
>
>
> I don't think I would call this a bug or a feature. I would, however,
> acknowledge that symbolic manipulation is a bit tricky in general.
>
> Mark McClure
Yes. Learning a CAS system well takes long time. In Mathematica this is
specially true because it is large and complex, more so now with the its use
of Dynamics[] which adds a new dimension to the whole way of how things
work.
But at the same time, if one can figure all these things out and how to use
them the right way and be able to walk the mine field without stepping on
something bad, Mathematica can really be a very powerful tool. I guess the
more powerful the tool becomes, the more skill one needs to use it correctly
else they can hurt themselves, and this seems to apply to CAS as to anything
else.
I am still trying to figure out how Dynamics really work in Mathematica. One
day I think I'll understand it ;)
--Nasser
....
>
>> In Mathematica, at least, this can be overcome with a combination of
>> Hold and ReleaseHold:
>
...
Mathematica has a whole bunch of stuff.
Hold HoldFirst NHoldAll SequenceHold
HoldAll HoldForm NHoldFirst $ConditionHold
HoldAllComplete HoldPattern NHoldRest
HoldComplete HoldRest ReleaseHold
Release,
these similar items in Mathematica may be useful in circumventing
certain behaviors, it does not mean that those behaviors are correct.
Those behaviors may still be bugs.
RJF
I never said that "(x^2)/x should have a subexpression of x^2 in it",
nor do I think it. I simply said that all the examples presented here
can be better understood as specific cases of the situation:
(a) User types in expr,
(b) expr is simplified,
(c) substitution is performed.
You have asserted that it would be great if a-I*b /. I->-I would yield
a+I*b and I actually agree. That doesn't make it a bug, as an
examination of the FullForm shows. I would certainly stop short of
calling it a "feature", however.
Mark
In Maple (which - to answer your latter question - is not free of
strange behaviours):
eval( (a+b*I)/(c-I*d), I=-I );
a - b I
-------
c + d I
There is a (non-recursive) command 'substitute' as well, it would do here.
For the other example given by Richard Fateman:
simplify( x^2, {x^2=y^4} );
4
y
This is called 'simplification with side relations' (=w.r.t equations).
It however would not work for simplify( 1/sqrt(x^3), {sqrt(x^3)=y} ),
the command needs polynomial relations.
And it does not work for constants like simplify( 1/sqrt(2), {2=y^2} ).
Wouldn't you want the result to be 1/x? Of course this works because
1/Complex[0,1] simplifies to Complex[0,-1] which matches the pattern
Complex[a_,b_].
> > In Mathematica, at least, this can be overcome with a combination of
> > Hold and ReleaseHold:
> > ----------------
> > In[2]:= ReleaseHold[Hold[1/Complex[0, 1]] /.
> > Complex[0, 1] -> x]
> > Out[2]= 1/x
> > ----------------
>
> Yes, the above works. But I think if one remembers the
> general complex replacement rule then then do not have
> to worry about using Hold etc.
To be clear, I was not suggesting that this is the correct way to
approach the problem; this simply makes it clear that the
simplification step is where the issue arises.
Mark
My view is that it is supposed to "do mathematics" as nearly as
possible, in the way that a user of mathematics might expect.
This is not always possible because two mathematicians might
disagree (especially if they are thinking in different sub-fields
of math.)
It helps if the "user" in question is
(a) A reasonably sophisticated user of mathematics -- perhaps an
engineer or physicist. Someone who has a significant context of
calculation, and is not just asking a one-off question like "shouldn't
sqrt(9) be -3 also?"
Note that some calculus students use mathematics, but they are just
learning it and may not have such a firm grasp of the issues, and
therefore sometimes request that a computer algebra system do something
that is sort of wrong. e.g. my book says log(abs(..)) but your system
leaves out the abs() so you must be wrong...
(b) Interested in algorithmic methods generally as a way of doing
mathematics. E.g. a user who vaguely describes a problem and vaguely
describes the answer to a similar problem, but has no idea of how to go
from the actual problem to the solution generally, is not going to find
a computer algebra system of much assistance. Such a "user" tends to
just post questions, perhaps to sci.math.symbolic in the hope (sometimes
fulfilled!) that some other reader will be familiar with the problem and
post a solution.
It is NOT my expectation that the user is a sophisticated programmer.
In fact, it is generally a disaster to build a system that can only be
used by programmers.
I do not expect that the user will be alert to the difference between
Complex[0,1], Complex[0,-1], and its relationship to -Complex[0,1]. (I,
-I, and something like Hold[-I]??).
I do not expect the user to know about the 14 Mathematica built-in
symbols that match the pattern *Hold*. I do not expect the user to know
about ANY of these symbols, since they do not occur in mathematics.
I do not expect the user to look at FullForm of an expression, unless it
is to satisfy some curious inclination (like how Mathematica
internally represents expressions in Lisp).
The contrary view, held by many respondents in the mathematica
newsgroup, follows. (Caution: I am going to exaggerate somewhat)
(a) No program is in error if it fulfills its specifications. Since the
specifications are probably not written elsewhere, you can be guided by
the program itself. If the program does what its source indicates it
should do, it's right.
(b) If the user does not like the result, then the obligation of the
maintenance programmer is to check the specification of the program and
see if the (allegedly dysfunctional) result is in agreement with the
spec. Of course it is, since the source code is in agreement with the
spec, which IS the source code.
(c) Since the result is by its nature the correct result, having come
from the computer [and computers don't lie] all that is left to do is to
scold the user, and/or suggest the user should become a programmer,
and/or suggest a workaround with a different spec.
(d) If the program is altered, it should be done by instructions from
above (not from a user). The user is merely a mathematician/ engineer /
physicist. The PROGRAMMER (and his boss) is in charge here.
This is not, I repeat NOT unique to any single computer algebra system.
It is historically quite common, and in my view, an embarrassment.
After all, if we said to AES, yes, None of the CAS
can substitute -I for I, using the obvious command, his logical
conclusion would be, I think, that the whole community is,
http://dan.hersam.com/lists/not_bright.html
..e.g. proof that evolution CAN go in reverse.
RJF
"To be clear, I was not suggesting that this is the correct way to
approach the problem; this simply makes it clear that the
simplification step is where the issue arises."
I was wondering which CAS system is considered the "best" when it comes to
the issue of substitution then?
Some have issues with how Mathematica does it for some cases. So, is there
then considered a best or a canonical way to approach this whole issue
instead of looking at as a case by case?
If there is one "best" way to approach expression substitution, what is it?
and which current CAS system does it? But I really think this is tied to how
the internal representation of expressions are implemented in the system.
May be some representation makes it easier to do things and harder to do
other things? Mathematica uses a FullForm, which is really nothing but an
expression tree which can be seen by typing the command
TreeForm[expression]
And this seems to me to be as a canonical way to do this as it would be
possible?
Maple seems to also have some issues with some specific cases of
substitutions.
I do know about sage or maxima and others.
--Nasser
>
> I was wondering which CAS system is considered the "best" when it comes to
> the issue of substitution then?
The problem of substitution is the name of a 1968 paper by A.C. Hearn,
the author of the CAS Reduce.
I could not find a copy of this paper online, however.
I wrote about "ratsubst" (in Macsyma) in my thesis, published in 1971.
Some people consider that the issue of simplification with respect to
polynomial side conditions is solved by Grobner bases.
>
> Some have issues with how Mathematica does it for some cases.
That is apparent.
So, is there
> then considered a best or a canonical way to approach this whole issue
> instead of looking at as a case by case?
>
For polynomials, especially smallish ones, there probably is a canonical
way, (or a collection of them) based on Grobner bases. In general this
is not necessarily helpful, nor does it address the full breadth of
expressions that are possible. Personally, I think that ratsubst (in
Maxima) is a pretty good tool; other systems now have similar facilities
I think. Look for simplification with respect to polynomial side relations.
....
> And this seems to me to be as a canonical way to do this as it would be
> possible?
You haven't defined canonical. The general concept is that for a CAS
form to be canonical, two mathematically equivalent expressions must
look identical when converted to that form. FullForm is not canonical
at all. FullForm[2*Cos[x]*Sin[x]] is different from FullForm[Sin[2*x]].
If you want to learn about simplification and substitution, I suggest
you go to the library (or look on the internet) and read, instead of
relying on the responses of people who happen to spend their afternoons
writing essays on sci.math.symbolic :)
> But at the same time, if one can figure all these things out and how to use
> them the right way and be able to walk the mine field without stepping on
> something bad, Mathematica can really be a very powerful tool. I guess the
> more powerful the tool becomes, the more skill one needs to use it correctly
> else they can hurt themselves, and this seems to apply to CAS as to anything
> else.
Nasser, I think no one -- well, at least very few -- will quarrel with
your first sentence.
The second one is very, very, very much more debatable.
>
> It is NOT my expectation that the user is a sophisticated programmer.
> In fact, it is generally a disaster to build a system that can only be
> used by programmers.
>
Do you know of a CAS system, which is powerful and yet can be used with
little programming skills from the user?
I do not think it is "can only be used by programmers" but more like "can be
better utilized by programmers".
Because for me, a CAS system IS a programming environment. It just happened
to be a programming environment specialized for mathematics.
Look also at Matlab for example, it is not really a CAS, but it requires
good programming skills to use it to solve the most basic engineering
problems. Even calculators these days, they come with 200 page manuals on
how to "program" them and just use them.
If one does not become a skilled programmer, then they will not be utilizing
the math software they are using to its full potential.
If you can come up with a CAS system that does not require one to become a
good programmer to use it well, then you could make a fortune, because your
system would have no competition in the Market place today.
--Nasser
Yes, any of them. It depends on what the user is doing. e.g. typing
into Matlab, Maxima, Mathematica, using some package designed for a
specific task. Some "toolbox" to get something done. No programming.
The idea, of an application specific language is at least 60 years old.
The problem is, CAS as we see them are not presented in any context.
For any REAL user, the CAS is seen in a specifc context of his/her
problem domain. And to argue, as Mathematica fans do, that the user's
context is wrong and he/she should learn to program around difficulties,
is often (not always) silly. If the user's context is so far from the
general stream of math, it is perhaps good to suggest the user build
some new programs.
If the user's context is such that the symbol I should appear as a
subexpression in the expression -I, then the user's context is RIGHT,
and the CAS that doesn't realize that has a BUG in it.
>
> I do not think it is "can only be used by programmers" but more like "can be
> better utilized by programmers".
In the same sense that a FORTRAN programmer can be better informed if
he/she also knows assembly language.
>
> Because for me, a CAS system IS a programming environment. It just happened
> to be a programming environment specialized for mathematics.
Has it occurred to you that most users have a job to do, and (contrary
to us) don't want to program?
>
> Look also at Matlab for example, it is not really a CAS, but it requires
> good programming skills to use it to solve the most basic engineering
> problems.
I think that this assertion is totally false.
Look at the manuals for toolboxes, which are what people buy Matlab
for. (Outside of academia).
Even calculators these days, they come with 200 page manuals on
> how to "program" them and just use them.
The reason the calculator manuals have so many pages is that they don't
know your context.
I happen to know people who use very elaborate calculators. They are
real estate brokers. Other than the numbers and + - *, then use 4 keys
that have to do with interest and payment schedules. They do not know
how to program.
>
> If one does not become a skilled programmer, then they will not be utilizing
> the math software they are using to its full potential.
Actually, I think the real estate brokers make excellent use of the
calculator, and it would be absurd for me to suggest that they are not,
because they don't know about the sinh function. Or even complex
numbers or square roots or division.
>
> If you can come up with a CAS system that does not require one to become a
> good programmer to use it well, then you could make a fortune, because your
> system would have no competition in the Market place today.
Again, false. What is needed is some killer application. E.g. if you
could convince real estate brokers that they needed a CAS, your CAS,
you'd be able to sell quite a few. Mathematicians? Even if every
person employed in the USA as a mathematician bought something, that
would be about 3,000. (According to bureau of labor statistics.)
[NOt counting people who TEACH mathematics. they are employed as
teachers, not mathematicians, again according to BLS].
RJF
>
> --Nasser
>
>
>
Do I understand you correctly that it is impossible in Maple to
substitute something for arbitrary subexpressions? Are only variables
(and predefined constants like I) allowed? Would
eval( 1/x^2, x^2 = y^4 );
or
eval( 2*cos(x^2), cos(x^2) = sin(y) );
be forbidden syntactically?
Martin.
>> Do you know of a CAS system, which is powerful and yet can be used with
>> little programming skills from the user?
>
> Yes, any of them. It depends on what the user is doing. e.g. typing into
> Matlab, Maxima, Mathematica, using some package designed for a specific
> task. Some "toolbox" to get something done. No programming.
> The idea, of an application specific language is at least 60 years old.
>
But you started, before, by saying this:
"It is NOT my expectation that the user is a sophisticated programmer. In
fact, it is generally a disaster to build a system that can only be used by
programmers."
Then now you say that if this same system provides a "toolbox" to do the
task at hand, then NO programming is needed.
Therefore, the same system you say is a disaster because it is build to be
used by only programmers can now suddenly become a system that does not
require any programming if there is a toolbox or a package to do the
specific task at hand so that the user does not have to become a programmer.
I agree. So the problem is now solved.
One can build a system that requires only programmers to be able to use it,
as long as they provide at the same time the toolboxes which a user who is
not a programmer can use.
So, then now we should look at which CAS system which best does the above.
i.e. comes with the most toolboxes and with the most higher level packages
which allows users to do sophisticated mathematics BUT with little
programming.
In this sense, I think Mathematica is doing better than the commercial
competition now. More and more advanced packages and higher level functions
come prebuild in the kernel. One can easily develop GUI to make small
applications and toolboxes.
So, we agree then that a CAS system can be very complex to program, and it
can require the most skilled programmers to use it, then this will be OK, as
long as it provides the toolboxes and the higher level packages to solve
user Mathematica needs so that do not have to do any programming themselves.
I will read the rest of you post and comment later if needed. Sorry, but
have to go now. class starts soon.
--Nasser
In Maple, x^2 is not a subexpression of 1/x^2, since the latter is
encoded as x^(-2). So this just returns 1/x^2 again.
>
> or
>
> eval( 2*cos(x^2), cos(x^2) = sin(y) );
This returns 2*sin(y)
>
> be forbidden syntactically?
>
They are not forbidden, just not so useful for your purpose.
--
G. A. Edgar http://www.math.ohio-state.edu/~edgar/
G A Edgar already said it, here is a bit more ...
2*x; subs(2=a, %); # or eval(%, 2=a);
x a
For 1/sqrt(2) it does not work, since it is given by 1/2*2^(1/2).
Note however:
eval( 1/sqrt(2), 2=y^2);
2 1/2
(y )
-------
2
thus the '2' in the two 1/2 of are not replaced. But with string
processing one certainly could enforce that (which should work
for replacing '-I' as well, but that is ugly for my taste).
I think that comes from the internal representation, which may be
different from what 'we' see & recognize or is shown on the screen
(Maple uses a DAG, a directed acyclic graph, but is too long ago
that I played with that, for me as user it usually is too deep in
the implementation details).
The simplify with side relations seems not to work for constants,
but the usual command works
simplify( 2, {2=y^2});
2
eval( 2, {2=y^2}); # or subs ...
2
y
As mentioned, the second example works, as is,
(**) eval( 2*cos(x^2), cos(x^2) = sin(y) );
2 sin(y)
For your first example, it matters that Maple stores (and only
recognizes, during some kinds of walk) the reciprocal as a negative
power.
(**) dismantle(1/x^2);
PROD(3)
NAME(4): x
INTNEG(2): -2
(**) expr := x^2 + 1/x^2:
(**) eval( expr, x^2 = y^4 );
4 1
y + ----
2
x
(**) eval( expr, x^(-2) = y^(-4) );
2 1
x + ----
4
y
(**) eval( expr, [x^2 = y^4, x^(-2) = y^(-4)] );
4 1
y + ----
4
y
This means that the internal layout affects how one codes for this
particular task. Fortunately, this is not the tip of too huge an
iceberg of similar issues, IMHO.
Maple also has `subs` and `algsubs` which, either alone or in
combination with its `frontend` command, can allow for more flexible
substitutions. There are also commands such as `patmatch`,
`tablelook`, `define`, etc.
See,
http://www.maplesoft.com/support/help
for online help on individual commands.
I consider functions like SIMPLIFY(), SUBSTITUTE(), EXPAND(), FACTOR(),
SOLVE(), SUM(), PRODUCT(), INTEGRATE(), DIFFERENTIATE(), LIMIT(),
DESOLVE(), 2DPLOT(), 3DPLOT() to be the *basic* functions of a Computer
Algebra system. In my perception, programming of a CAS means to cause
the automated (often repeated) execution of a combination of these. Both
the user who types in single commands and the programmer of a CAS should
be protected from the details of the internal symbolic representation
(say, whether #i is an atomic symbol), much like the average C++
programmer need not bother about the details of the IEEE floating point
standard (say, how exponent signs are represented). As a rule, he *can*
be protected. And he usually is.
A SUBSTITUTE command that overlooks #i in -#i on a system displaying
COMPLEX(0,-1) as -#i fails in this respect. Same for x^2 in 1/x^2 on a
system that displays x^(-2) as 1/x^2. Both substitutions are often
mathematically sensible, they are often done in the mind and on paper.
I think, this kind of intelligent behavior only increases the power of a
Computer Algebra system. Its absence is not required by a system's
power; its presence does not undermine a system's power. But a system is
restained by the requirement of backward compatibility. If your sine
function was initially implemented as SIN(SQRT(x^2)), the full function
will have to be called EULER_SINE() or SinusEuleri[] henceforth - that's
what happend to Mathematica's Lerch[z,s,a]. For the same reason,
Mathematica's substitution operator /. would have to be retired if it
were to become more intelligent. This may explain a lot of resistance to
the idea.
Martin.
The fundamental problem is that the symbolic structure of an
expression in your mind is not necessarily the same as it is in the
computer. Mathematica's FullForm (how it sees the expression) is at
least well defined (not session dependent and described by clear
rules).
It can be appealing to expect the way that Mathematica sees the
expression to be the same way that it displays the expression. But
Mathematica allows you to present your output in many different ways.
The linear InputForm, the 2D standard form, the 2D but more ambiguous
TraditionalForm, specific target forms like TeXForm, and FortranForm
etc and forms that you can define yourself as well as FullForm. The
behaviour of ReplaceAll (/.) can't be consistent with all of these.
I think that the idea that there is some kind of "common sense" mix of
these rules, in the end trades simpler operation for simple cases for
harder operation for hard cases. I can't immediately imagine how I
would specify the opposite cases of "replace I in Sin[I] but not in Sin
[3+I] and x^2 in 1+x^2 but not in 1/x^2" if those equivalents were
automated.
So an "intelligent" replacement would be nice but is not an
alternative to the existing ReplaceAll. Here is an implementation of
the two examples given in this thread by transforming the user stated
transformation rules into a more complicated set of generated
transformation rules.
FullReplaceAll[expr_, rules_] :=
expr /. Flatten[
rules /. {
HoldPattern[Rule[var_^pow_, rep_]] -> {Rule[var^pow, rep], Rule
[var^(-pow), 1/rep]},
HoldPattern[Rule[Complex[0, 1], rep2_]] -> Rule[Complex[a_, b_],
(a + b rep2)]
}];
In[4]:= FullReplaceAll[(3 + I)/(x^2), {x^2 -> y, I -> t}]
Out[4]= (3 + t)/y
One could easily extend this code, but I think things get more
problematic after these obvious cases, if you use the "what you see"
as a guide of what transformations should be made...
x^3/.(3->n) gives x^n
but should
x^(1/2)/.(1/2->n) not change at all because x^(1/2) displays with a
square root sign with no "1/2" to be seen?
Should Transpose[x]/.T->n return x^n because in TraditionalForm
Transpose formats as x superscript T?
In my opinion, the user of a Computer Algebra system should generally
try to match the symbolic structure in his mind to the notation used by
the system, or preferably vice versa, and for efficient work the
notation should thus be the same for input and output (possibly up to a
minimally intrusive mapping detailed below). By all means, user input
should therefore be permitted to be entered, and should by default be
interpreted, in accordance with the (current) output style of a system.
Thus, if my results are produced in reverse Polish Notation I should
prefer to think in RPN and generate my input in RPN, if complex numbers
are displayed as Complex[a,b] one should think in terms of the Gaussian
plane and type in coordinate pairs, etc.
When matrix transposition is written as A^t, we are dealing with an
example of semantic ambiguity of standard mathematical notation, which
is present in TeX typesetting instructions as well. But obviously the
behavior of a CAS substitution operator with respect to the replacement
of subexpression like x^2 can be made consistent with any other output
format that is semantically unambiguous and constitutes valid system
input. The interpretation as input of ambiguous formats where matrix
transposition is written as ^t, etc., should probably not be attempted,
and the use of FORTRAN as input language should never be considered:
once FORTRAN is enhanced to allow the specification of any otherwise
valid CAS input, 95% of it wouldn't be FORTRAN anymore.
With respect to ambiguous output formats as well as other formats that
do not immediately constitute valid input, I suppose that a Mathematica
user can still copy-and-paste an output expression (or perhaps a
cursor-selected part of it), and thereby bring up a semantically
unmambiguous equivalent string of characters that constitutes valid
system input and also preserves as many details of the output style as
possible: in particular term order, parenthetical structure (supplying
all those, and only those, parentheses necessary, which may be more than
explicitly shown in the output), and of course x^(1/2) versus Sqrt[x],
x^(-2) versus 1/x^2, Complex[0,-1] versus -I, etc. When fed back into
the system the string must always reproduce the output it represents. I
suppose this kind of "reference representation" is kept in petto anyway
to avoid a back-conversion from semantically ambiguous or graphical
output formats.
By making the SUBST() operator of a Computer Algebra system refer to
this reference representation for the current default output format,
users would no longer be required to convert mentally between different
formats (or to even know that alternative formats exist) in order to
understand its behavior - a case of WYSIWYG. If a system possesses more
than one output format, the SUBST() operator should have options to
select among the formats possible; if a system can be configured to
produce more than one format automatically, the default replacement
behavior will change with the format setting. Unless the default is
overridden by a specific choice of option, the results of subexpression
replacement thus become dependent on the system configuration, but this
is no problem since CAS results depend on variable assignments anyway;
there is no new kind of session dependence.
In short, a SUBST() operator should make replacements always to the
extent that, according to the (current) default output style, the
reference representation of the subexpression to be replaced is present
in the reference representation of the main argument. I think this
answers all of your objections as to how an intelligent substitution
operator could unambiguously deal with the presence or absence of the
subexpressions 1/2, or 1+x^2 and 1/x^2, or SIN(#i) and SIN(3+#i). Just
allow Mathematica's /. operator to refer to any permissible output
format, with an intelligent choice of default, rather than exclusively
to the FullForm internal format.
Martin.
I'd agree with this 100%.
Given you write Mathematica code in the Mathematica language, then even
one-liners like
In[1]:= 10!
Out[2]= 3628800
is programming. You can do a reasonable amount in Mathematica knowing little
more than a few basic commands, with no significant programming effort.
But sooner or later you are going to want to do things that require more
advanced programming skills. If you do not, then you probably did not need to
buy Mathematica in the first place.
--
I respectfully request that this message is not archived by companies as
unscrupulous as 'Experts Exchange' . In case you are unaware,
'Experts Exchange' take questions posted on the web and try to find
idiots stupid enough to pay for the answers, which were posted freely
by others. They are leeches.
> But sooner or later you are going to want to do things that require more
> advanced programming skills. If you do not, then you probably did not
> need to buy Mathematica in the first place.
>
To reply to my own post, it is worth noting there is a free 408 page book
"Mathematica programming: An advanced Introduction"
written by Leonid Shifrin, released under the Creative Commons License, which
may be read online or downloaded as a PDF.
http://www.mathprogramming-intro.org/
Yes, there are people who build toolboxes, who are, to some extent,
programmers.
There are people who use toolboxes, who may be non-programmers.
Like iPhones.
>
> Therefore, the same system you say is a disaster because it is build to be
> used by only programmers can now suddenly become a system that does not
> require any programming if there is a toolbox or a package to do the
> specific task at hand so that the user does not have to become a programmer.
In the context of a toolbox, yes. You, however are talking about the
raw Mathematica interface
and how it is supposed to deceive the user regarding I and -I, and you
are defending this obvious bug
as a feature.
>
> I agree. So the problem is now solved.
You can agree with me, but I don't agree with you that the problem is
solved.
>
> One can build a system that requires only programmers to be able to use it,
> as long as they provide at the same time the toolboxes which a user who is
> not a programmer can use.
Sure, that first system is called a Programming Language. An example
is Lisp.
If you say Mathematica is intended as a programming language, and not
to be used
by "end users" ever, that would be an interesting assertion contrary
to its usual billing.
>
> So, then now we should look at which CAS system which best does the above.
Sure. Here are the choices: C, Lisp, Aldor, Python, Ruby, PHP... All
of these can be
used to build other things.
> i.e. comes with the most toolboxes and with the most higher level packages
> which allows users to do sophisticated mathematics BUT with little
> programming.
suddenly you require "little" programming??
>
> In this sense, I think Mathematica is doing better than the commercial
> competition now. More and more advanced packages and higher level functions
> come prebuild in the kernel.
The wrong place for an application,generally. And Mathematica clearly
does a poor job of supporting application writers by providing a bug-
ridden interface to its actual kernel, where -I is such a problem.
> One can easily develop GUI to make small
> applications and toolboxes.
No, because the system has quite a few gotchas. Just read the
mathematica newsgroup.
>
> So, we agree then that a CAS system can be very complex to program, and it
> can require the most skilled programmers to use it, then this will be OK, as
> long as it provides the toolboxes and the higher level packages to solve
> user Mathematica needs so that do not have to do any programming themselves.
You can say whatever you say about your own beliefs, but in general,
don't put words in MY mouth.
You can agree with me, but don't say that I agree with you. And don't
restate what I said unless you do it accurately.
I did not ever ever say that it is OK for a CAS to require the user
to be a skilled programmer.
Only you said that. I do not agree with that. I think it is
important that a CAS not have bugs, and that when a bug is identified,
like this -I business, it should be fixed. Not declared a feature.
It is easy to fix.
As I've previously said, there are times that there are legitimate
disagreements about what a system should do because math notation etc
is sometimes ambiguous.
This is not one.
RJF
>> In this sense, I think Mathematica is doing better than the commercial
>> competition now. More and more advanced packages and higher level functions
>> come prebuild in the kernel.
>
> The wrong place for an application,generally. And Mathematica clearly
> does a poor job of supporting application writers by providing a bug-
> ridden interface to its actual kernel, where -I is such a problem.
I suspect one of the reasons for doing this it to ensure end-users can't see the
algorithms used. Even if that is not the intension, it is an unfortunate
side-effect.
Also, the term 'kernel' is used very differently by Wolfram Research to the way
it is used in the design of a Unix operating system. As such, I do not see why
implementing more functionality in the kernel of Mathematica is a bad thing. To
do so in a Unix kernel would be crazy, but I do not believe WRI are wrong to do so.
BTW, have you ever used ListPolarPlot in Mathematica which were I believe
introduced in version 6? Unless they have improved dramatically in 7, the
package PolarListPlot by Ted Ersek in the Wolfram library is *considerably*
better, though it needs some changes as WRI have broken backward compatibility.
It seems that Ted wrote the package since he wanted to use polar plots, whereas
the person in WRI who wrote ListPolarPlot did it because they were told to do so.
I think it was done originally to implement the system in an object
variant of C, in which huge parts of Mathematica were originally
implemented, and I think are still implemented. The kernel was
supposed to be fast, and traditionally would be small except WRI
didn't seem to use that idea.
They seem to be moving more toward implementing packages in
Mathematica, which would in some sense
validate their system design for the Mathematica language. I view the
large parts of Mathematica
system that are NOT written in Mathematica as a disproof of concept.
Compare to Maple, in which everything that could be taken out of the
kernel was taken out.
I don't know the size of the kernel now, but it used to be tiny. It
may have become bloated by
GUI stuff and plotting, and maybe hairier numerics. But it would be
unlikely in the Maple view
to augment symbolic math e.g. integration, in C.
\
>
> Also, the term 'kernel' is used very differently by Wolfram Research to the way
> it is used in the design of a Unix operating system. As such, I do not see why
> implementing more functionality in the kernel of Mathematica is a bad thing.
I think it depends on what functionality you mean. The Signal
Processing Toolbox of Matlab is
"functionality" but I don't think it appropriate to put it in the
kernel of Mathematica (though
some special pieces might be -- e.g. some FFT that has to be
especially efficient.)
To
> do so in a Unix kernel would be crazy, but I do not believe WRI are wrong to do so.
I disagree.
>
> BTW, have you ever used ListPolarPlot in Mathematica.
No.