When asking to
integrate(1/(1 - cos(phi)^2*sin(x)^2), x, 0, %pi/2);
the user is asked "Is 1 zero or nonzero?", which is somewhat funny, somewhat strange, and gives no clue about whats going on. Adding "trace(?asksign1);" reveals that integrate wants to know the sign of "4cos (phi) ^2 - 4" which would have been precious to the user, and would have suggested a "assume(4cos (phi)^2 - 4 < 0)".
But what is more disturbing is, how did this question come up at all when looking
at "cos^2 - 1". How did it internally arrive at a point from where the sign of "1" would become interesting.
Thus more interesting is this trace
trace(?asksign1);
trace(?sign\-prep);
trace(?ensure\-sign);
trace(?sign1);
asksign(cos(phi)^2 - 1);
from a glimpse at the trace printout, and another glimpse at "compar.lisp"
I'd guess there is too much passing values by "special" variables from
function to function, and something might have been overwritten that way.
I think it is worth having a thorough look at this testcase.
Regards,
Robert
The "Is 1 zero or nonzero?" bug has been with us for a long time--it pops up occasionally. I'd guess the source code has workarounds for this bug, but it's never been fixed.
Any help or insight to fixing this bug would be terrific.
this shorter testcase:
without the square is easier to trace and is sufficient for debugging.
in compar.lisp there is (defun asksign1...) which invokes (sign1 ...) on the given expression.
Here the result will be
$NZwhich I guess shall mean negative or zero.so far so good.
then a (cond ) follows and the (null odds) will be choosen.
here the defun argument $askexp will be setq'ed to something new, namly (lmul evens).
it happens evens is nil, and lmul returns
1for this.few lines deeper the interactive function ensure-sign will be invoked with this new expression being "1" as the user shall now decide either pos neg or zero, the $nz was not decisive enough.
and thus we are asked whether "1" is zero.
problem is, I don't know what
evensandoddsis meant to be. I can only guess the caseof both being nil was not anticipated.
By the way, while stepping through the code somewhere around sign1 I saw integer numbers
1 and 0 being converted to floats. isnt that ugly for a symbolic engine ?. futhermore there is
somewhere a < 1e-6 in compar.lisp which seems even uglier.
Evens and odds are subexpressions that are even or odd functions. They are dynamic variables that are set in various places in compar.lisp. Old-fashioned coding style, but....
How exactly do you think the whole expression is related to the subexpression ?
for example
do you think this gives rise to
special variable minus being t
odds being a list of y and (y+2)
evens being a list of x and (x+1)
is it meant to work that way ?
then I'd expect
to be split into
minus nil
odds list with one element (1-cos(x))
evens nil
Regards,
Robert
Yes, $NZ is negative or zero, $PZ is positive or zero, and ... The user documentation for sign (enter ? sign) lists all possibilities for the output of sign.
About
evensandodds. It seems that since there are no even expressions and no odd expressions, asksign1 should be free to return $NZ?Yes, it is ugly. What happens if you disable it? Does the testsuite run to completion?
"Barton Willis" willisbl@users.sourceforge.net writes:
I don't think so. There is some place in signdiff-special where it
actually looks at cos(x)+constant, and makes up its mind.
Here cos(x)-1 will be correctly decided to be $nz, negative or zero.
But asksign1 can only return positive zero or negative, thus $nz is not
precise enough. Thus it decides to interact with the user and ask him with
the function ensure-sign. and before it invokes this it reassembles a
expression $askexp which originally was cos(phi)-1 which will then be
presented to the user instead of the original expression. It reassembles this
from the odds and evens list only, and because both of them are empty
and because the reassembly is done by (lmul...) presumable "multiply all
things in a list", empty list counts as "1". Maybe one simply shouldnt
setq to $askexp when both lists are empty. But this is difficult to
decide for me with all those special vars around and with my exremly
limited understanding of whats going on here.
here is an example:
asksign((cos(phi)-1) * phi^2 * rho^3)
will produce an odds list with the single element rho
and an evens list with the single element phi
the reassembly then produces
odds * evens^2 --> rho * phi^2
less exponents but still sufficient to find the sign.
It is by far not that easy that I could try it. I just wondered why such
things pop up during my tracing action. in cos(phi) - 1 there is no
float whatsoever to be seen, and nontheless suddenly they pop up in the
trace. certainly it has nothing to do with the "1" question thing.
things get worse.
If I asksign((cos(x) - 1) * phi^3)
it will ask me "Is phi positive, negative or zero?"
it asks me only about phi.
If I answer positive then its response is "pos" which is clearly completely bogus.
Thus is not only forgets to reassemble the cos(x)-1 into the $askexp variable when
preparing for the interactive question in ensure-sign. It completely forgets that this part is $nz.
Here is a possible patch (not well-tested):
That's enough to avoid "Is 1 negative or zero?" mentioned in this report. I haven't tried existing bug reports about "Is 1 something or the other?".
It doesn't change the results for the "forgotten term" bugs also mentioned in this bug report; those probably need a separate report.
I'd propose something too, almost untested.
Inspired by something similiar found in signsum but absent in signdiff.
I will need some time to check and think about it.
make check works.
asksign(cos(x)-1) and some others work.
but asksign(1-cos(x)) somewhere looses a sign.
I attach a revised patch which cares about the sign problem as well.
make check works,
batch("maxima-code/tests/test_asksign1.mac", test); works
first remove an ancient leftover artifact
then try to fix the issues:
which fixes tree issues:
1) 1-cos did pose the "1" question, because odds was not set
2) abs(x)-x did pose the "1" question, because odds was not set
3) when the "1" question was fixed, 1-cos posed an incorrect question
because the domain was not flipped when minus was set
here is a bit of a test facility, for debugging purpose only.
It is ment to check not only askasign1 return values, but as well the
asked domain questions ant their expressions.
it can be run like this:
batch("maxima-code/tests/test_asksign1.mac", test);
some tests are stolen from rtest_ask, others popped up during search for the bug.
test_asksign1.mac is attached.