|
|
last edited 10 years ago by test1 |
1 2 3 4 5 6 7 8 | ||
Editor: kratt6
Time: 2007/12/28 12:36:13 GMT-8 |
||
Note: fixed in FriCAS |
changed: -gives '%i %pi' gives $\pi$, as it should.
Is the following a case of total simplification failure (a certain bug from the user's point... unless AXIOM is not targeted for Martians who as known have no need in simplification whatsoever :)
or
it is still possible to get %pi out of the lengthy expression
axiom%i*log(-%i) - %i*log(%i)
(1) |
?
Given my previous posting about complexForm, I mean maybe just a way to expel those nasty logarithms and see the real and imaginary parts not intertwined rather than a correct answer.
Any, maybe even a very cumbersome way?
.....................................................................
axiomsimplify(%i*log(-%i) - %i*log(%i))
(2) |
axiomnormalize(%i*log(-%i) - %i*log(%i))
(3) |
axiomcomplexNormalize(%i*log(-%i) - %i*log(%i))
(4) |
.....................................................................
COMPARE:
Derive 6.1> LOG(#i) - LOG(-#i) gives #i*pi Maple 9.5.2> ln(I) - ln(-I); gives I*Pi MuPAD 3.1> ln(I) - ln(-I); gives I*PI Mathematica 5.1> Log[I] - Log[-I] gives I*Pi Maxima 5.9.1> RECTFORM(LOG(%I) - LOG(-%I)); gives %I %PI
However:
AXIOM -> complexForm(log(%i) - log(-%i)) gives 0
The problem is in the operation "argument":
axiomargument(%i)
(5) |
axiomargument(-%i)
(6) |
the latter should be -pi/2, of course. The problem is in gaussian.spad, COMPCAT:
if R has TranscendentalFunctionCategory then half := recip(2::R)::R if R has RealNumberSystem then atan2loc(y: R, x: R): R == pi1 := pi()$R pi2 := pi1 * half x = 0 => if y >= 0 then pi2 else -pi2 -- Atan in (-pi/2,pi/2] theta := atan(y * recip(x)::R) while theta <= -pi2 repeat theta := theta + pi1 while theta > pi2 repeat theta := theta - pi1 x >= 0 => theta -- I or IV if y >= 0 then theta + pi1 -- II else theta - pi1 -- III argument x == atan2loc(imag x, real x) else -- Not ordered so dictate two quadrants argument x == zero? real x => pi()$R * half atan(imag(x) * recip(real x)::R)
so the problem occurs if R does not have "RealNumberSystem?":
axiomargument(-%i*1.0)
(7) |
since Float does have RNS, but INT does not. I'm not quite sure what the condition should be. OrderedSet??
OrderedRing
, probably. OrderedSet
, wouldn't make sense...
Martin
Status: open => fix proposed Severity: normal => critical Hm, replacingRealNumberSystem
with OrderedRing
does not really work, since EXPR INT
does not have OrderedRing
... Furthermore, FRAC INT
does not have TRAFUN
... On the other hand, asking for TranscendentalFunctionCategory
also seems a lot, since only division by two is required.
Questions:
EXPR INT
have OrderedRing
?TRAFUN
really necessary?
On the other hand, asking for TranscendentalFunctionCategory
also seems a lot, since only division by two is required.
Looking at the code above, to define argument
in COMPCAT R
, it seems we need, other than arithmetic in RING
, the following:
R has OrderedSet atan: % -> % zero?: R -> Boolean recip: % -> Union(%,"failed") pi: () -> R
axiommyhalf: ()-> EXPR INT
axiommyhalf()==recip(2::EXPR INT)::EXPR INT
axiommyArgument: Complex EXPR INT -> EXPR INT
axiommyArgument(x) == zero? real x => imag(x) > 0 => pi()$(EXPR INT) * myhalf() imag(x) < 0 => - pi()$(EXPR INT) * myhalf() error "myArgument not defined at (0,0)" atan(imag(x)*recip(real(x)))
axiommyArgument(-%i)
Compiling function myhalf with type () -> Expression Integer
Compiling function myArgument with type Complex Expression Integer -> Expression Integer
(8) |
axiommyArgument(%i)
(9) |
axiommyArgument(3+5*%i)
(10) |
axiommyArgument(3-5*%i)
(11) |
axiommyArgument(0::Complex EXPR INT) Error signalled from user code in function myArgument: myArgument not defined at (0,0)
Note, I think the current returns by argument(0::Complex EXPR INT)
and argument(0::Complex INT)
as %pi/2
are wrong.
axiomargument(0::Complex INT) >> Error detected within library code: (1 . failed) cannot be coerced to mode (Expression (Integer))
* ShouldEXPR INT
haveOrderedRing
?
Even POLY INT
does not have OrderedRing
and the reason given was to allow EXPR
to implement abs
. I thought about this briefly and wonder what abs
of a polynomial really should be and find no satisfactory answer (one possibility is to define it relative to a term-ordering as the abs
of the leading coefficient). You probably noted that OrderedRing
is not the same as Join(OrderedSet, Ring)
. One use of ORDRING
is to step through a segment. Clearly, there is no canonical meaning to stepping from one expression (or polynomial) to another (since some term-orderings like pure lex is not sequential because there may be infinitely many monomials between two).
* Is TRAFUN
really necessary?
You meant TRANFUN
? (Maybe it's not since searching hyperdoc with *TRANFUN*
under constructors only returns FortranFunctionCategory
:-). Seriously, I believe the reason is, like any other categories in Axiom, to allow multiple domains in the category (say due to the different data-representations or algorithms, or whether one wants symbolic computation or numerical), but to also provide a few default implementations valid across all domains of the category (unless overridden for some more efficient implementations).
In Axiom, it is easy (and we are sometimes forced) to spin out these hierarchical categories and domains of abstractions. In any other system, such abstractions are not really necessary because the author usually dictates every choice (notation, algorithm, input, output conventions). I once worked with a bright undergraduate student on developing something intended to be partial differential polynomial ring (where derivations are abstract operators, not necessarily the d/dx type) and wanted a flexible way to input/output partial differential algebraic equations (something rather simple?) and the number of categories and domains simply proliferated. One of the main hurdles is ordering the pieces (a general multivariate partial differential monomial carries a lot of data and notation). The student quitted, unfortunately leaving no notes of our numerous discussions on the design. I wonder whether MB worked alone on the design for transcendental functions or wrote notes to himself at least.
William
The proposed definitionmyArgument
is still not correct:
axiommyArgument(-1+%i)
(12) |
but should be . We cannot get around the ordering of the ring involved... Of course, as soon as variables are involved, we cannot know anymore in which quadrant we are. So in this case we really should return argument
unevaluated. This would probably involve making it an operator. A different possibility would be to introduce a new two argument operator atan
paralleling the one in Float
and DoubleFloat
.
Martin
Martin:Thanks for pointing out my error. In coding myArgument
, I was not aiming for a general definition. I was experimenting to see if there is need for RealNumberSystem
or OrderedRing
.
As you proposed, it seems the error in myArgument
may be fixed by a two argument version of atan
(which only exists for Float
and DoubleFloat
currently). The usual sign convention will take care of the case of inputs involving variables. But I am not convinced one way or the other that OrderedRing
is needed.
axiommyhalf: ()-> EXPR INT Compiled code for myhalf has been cleared. Compiled code for myArgument has been cleared.
axiommyhalf()==recip(2::EXPR INT)::EXPR INT 1 old definition(s) deleted for function or rule myhalf
axiompi1:= pi()$(EXPR INT)
(13) |
axiompi2 := pi1 * myhalf()
Compiling function myhalf with type () -> Expression Integer
(14) |
axiommyatan2(x:EXPR INT, y: EXPR INT): EXPR INT == x = 0 => if y >= 0 then %pi else -%pi -- Atan in (-pi/2,pi/2] theta := atan(y * recip(x)::EXPR INT) -- may create infinite loop if variables are used in input -- in any case, why would atan give a result outside (-pi/2, pi/2]? -- while theta <= -pi2 repeat theta := theta + pi1 -- while theta > pi2 repeat theta := theta - pi1 x >= 0 => theta -- I or IV if y >= 0 then theta + pi1 -- II else theta - pi1 -- III Function declaration myatan2 : (Expression Integer,Expression Integer) -> Expression Integer has been added to workspace.
axiommyatan2(1,-1)
Compiling function myatan2 with type (Expression Integer,Expression Integer) -> Expression Integer
(15) |
axiommyatan2(x,y)
(16) |
axiommyArgument: Complex EXPR INT -> EXPR INT
axiommyArgument(x) == zero? real x => imag(x) > 0 => pi2 imag(x) < 0 => - pi2 error "myArgument not defined at (0,0)" myatan2(real x, imag x) 1 old definition(s) deleted for function or rule myArgument
axiommyArgument(-%i)
Compiling function myArgument with type Complex Expression Integer -> Expression Integer
(17) |
axiommyArgument(%i)
(18) |
axiommyArgument(3+5*%i)
(19) |
axiommyArgument(3-5*%i)
(20) |
axiommyArgument(-1+%i)
(21) |
axiommyArgument(2 - x*%i)
(22) |
axiommyArgument(0::Complex EXPR INT) Error signalled from user code in function myArgument: myArgument not defined at (0,0)
William
Dear William,I think that the "usual sign convention" is a bad idea. myatan2(x,y)
should return unevaluated, since there is no way of knowing in which quadrant x+%i*y
is. That's why I proposed OrderedRing
, in which case the answer is clear. We would have to think of the case of members of COMPLEX EXPR INT
where we happen to know the quadrant.
Martin
Dear Martin:Thanks, and yes, I was wrong again (shame on me): the range of the single argument atan
does not cover . But the only way to return results in case variables are involved in the arguments of atan(x,y)
is to use provisos (I thought I was able to avoid this with the sign convention). Even if we were able to make EXPR INT
into an OrderedRing
, the tests such as if y > 0 then
will have a different meaning than when y
takes a value in INT
whatever the ordering on EXPR INT
may be. Such tests must be done using values of y
, not the expression represented by y
(thus, the code for myatan2
used these tests incorrectly for general expressions y
). So it seems we need OrderedRing
not on EXPR INT
but on INT
, which is okay, except that in COMPLEX R
we have no way to know about what R
is (see also last paragraph in this reply).
One possible way is to use a three argument atan
: in addition to the x,y
coordinates, also include the quadrant. This would allow a user to supply the crucial information and also make it automatic when the quadrant can be deduced. We can allow the quadrant information to be specified as unknown
or failed
and then return the expression unevaluated in that case.
The amount of simplification that should be carried out should also be part of the discussions. For example, in a two-argument version, atan(2*(x^2+1),(x^2+1))
should be evaluated to atan(1/2)
but any such simplification either is difficult (not possible?) or may lose information on the quadrant if not carefully done. For example, atan(2*(x^2+1),-(x^2+1))
and atan(-2*(x^2+1), (x^2+1))
should give different answers. But how can we test signs on expressions? (Note that this is different from how to make EXPR INT
into an OrderedRing
because we are talking really on the level of the base domain: signs of expressions as values, not as expressions.) It would seem that we need to get into the full-blown cylindrical algebraic decomposition (CAD) stuff, even just for the polynomial expressions. And INT
is not quite the base domain to perform these computations.
Stepping back a bit, let's see why EXPR INT
is involved in the original post to evaluate argument(-%i)
. Functions (and especially, when implemented as operators) like argument
and atan
perhaps should be defined only under a domain which is closed with respect to them (so argument: Complex R -> R
would be considered closed, but argument: Complex Integer -> Expression Integer
would not.) In Complex Integer
these functions are meaningful only because the set of Gaussian integers is mathematically a subset of the field of complex numbers. The Axiom construction is complicated by the fact that may be symbolic and hence lives in Expression R
. And once expanded to Expression R
, the problem with what to do with variable inputs further complicates the implementation. Thus in evaluating argument((-1+%i)::Complex Integer)
, Axiom needs to invoke argument: Complex EXPR INT->EXPR INT
. Would it be appropriate to invoke something like argument: Complex Float -> Float
instead? (This would avoid the issue of variables in input arguments.)
This discussion naturally leads one to question why specific constants such as live in separate domains in Axiom (contrary to a purely mathematical model). Must these constants be numerically represented under Float
? Can one create something called SymbolicFloat
where roughly, SymbolicFloat
is a mix of floating point numbers, symbolic algebraic numbers, and symbolic transcendental numbers, and yet retains the properties of RealNumberSystem
and OrderedRing
(so whenever an inequality in this domain is to be tested, all symbolic constants will be temporarily converted to floating point with an accuracy sufficient to resolve the decision, but the symbolic constants still remain symbolic in subsequent computations)?
William
see #141 atan(tan(3)) => 3 Thanks for this pointer. I would prefer to classifytan(3)
as belonging to the hypothetical SymbolicFloat
rather than to EXPR INT
and the same for atan(tan(3))
. The definition of the single argument atan
chooses by convention a unique answer in where tan
is monotone. Axiom is constrained by its type system to provide an answer within EXPR INT
and view atan
as a more generalized inverse (that is, no longer a function) and multiple answers are possible. The (applied) scientific community probably prefers invoking the Float
or DoubleFloat
version of atan
and tan
, and they can, by simply changing 3
to 3.0
.
see [RealNumbers]? and #167 for more info and discussions on infinite precision floats and exact real number computations.
I think we could simply add a definition of a two argument version of atan
to ElementaryFunction
, where we can ask for OrderedRing
. I'll try to propose a definition tomorrow.
Martin
Status: fix proposed => open Category: Axiom Mathematics => Axiom Library Status: open => fix proposedaxiomcomplexForm(%i*log(-%i) - %i*log(%i))
(23) |
gives , as it should.